diff options
-rw-r--r-- | drivers/s390/net/qeth_core_main.c | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 19a6ee01bee3..44d32000a09e 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -6125,27 +6125,38 @@ static int qeth_set_ipa_tso(struct qeth_card *card, int on) int qeth_set_features(struct net_device *dev, netdev_features_t features) { struct qeth_card *card = dev->ml_priv; - netdev_features_t changed = card->dev->features ^ features; + netdev_features_t changed = dev->features ^ features; int rc = 0; QETH_DBF_TEXT(SETUP, 2, "setfeat"); QETH_DBF_HEX(SETUP, 2, &features, sizeof(features)); - if (card->state == CARD_STATE_DOWN || - card->state == CARD_STATE_RECOVER) - return 0; - - if ((changed & NETIF_F_IP_CSUM)) + if ((changed & NETIF_F_IP_CSUM)) { rc = qeth_set_ipa_csum(card, features & NETIF_F_IP_CSUM ? 1 : 0, IPA_OUTBOUND_CHECKSUM); - if ((changed & NETIF_F_RXCSUM)) - rc |= qeth_set_ipa_csum(card, + if (rc) + changed ^= NETIF_F_IP_CSUM; + } + if ((changed & NETIF_F_RXCSUM)) { + rc = qeth_set_ipa_csum(card, features & NETIF_F_RXCSUM ? 1 : 0, IPA_INBOUND_CHECKSUM); - if ((changed & NETIF_F_TSO)) - rc |= qeth_set_ipa_tso(card, features & NETIF_F_TSO ? 1 : 0); - return rc ? -EIO : 0; + if (rc) + changed ^= NETIF_F_RXCSUM; + } + if ((changed & NETIF_F_TSO)) { + rc = qeth_set_ipa_tso(card, features & NETIF_F_TSO ? 1 : 0); + if (rc) + changed ^= NETIF_F_TSO; + } + + /* everything changed successfully? */ + if ((dev->features ^ features) == changed) + return 0; + /* something went wrong. save changed features and return error */ + dev->features ^= changed; + return -EIO; } EXPORT_SYMBOL_GPL(qeth_set_features); @@ -6164,6 +6175,11 @@ netdev_features_t qeth_fix_features(struct net_device *dev, dev_info(&card->gdev->dev, "Outbound TSO not supported on %s\n", QETH_CARD_IFNAME(card)); } + /* if the card isn't up, remove features that require hw changes */ + if (card->state == CARD_STATE_DOWN || + card->state == CARD_STATE_RECOVER) + features = features & ~(NETIF_F_IP_CSUM | NETIF_F_RXCSUM | + NETIF_F_TSO); QETH_DBF_HEX(SETUP, 2, &features, sizeof(features)); return features; } |