Skip to content

Commit

Permalink
qeth: restore device features after recovery
Browse files Browse the repository at this point in the history
After device recovery, only a basic set of network device features is
enabled on the device. If features like checksum offloading or TSO were
enabled by the user before the recovery, this results in a mismatch
between the network device features, that the kernel assumes to be
enabled on the device, and the features actually enabled on the device.

This patch tries to restore previously set features, that require
changes on the device, after the recovery of a device. In case of an
error, the network device's features are changed to contain only the
features that are actually turned on.

Signed-off-by: Hans Wippel <[email protected]>
Signed-off-by: Ursula Braun <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
Hans Wippel authored and davem330 committed Sep 16, 2016
1 parent bc6c03f commit e830baa
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 0 deletions.
1 change: 1 addition & 0 deletions drivers/s390/net/qeth_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -999,6 +999,7 @@ struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *,
__u16, __u16,
enum qeth_prot_versions);
int qeth_set_features(struct net_device *, netdev_features_t);
int qeth_recover_features(struct net_device *);
netdev_features_t qeth_fix_features(struct net_device *, netdev_features_t);

/* exports for OSN */
Expand Down
29 changes: 29 additions & 0 deletions drivers/s390/net/qeth_core_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -6131,6 +6131,35 @@ static int qeth_set_ipa_tso(struct qeth_card *card, int on)
return rc;
}

/* try to restore device features on a device after recovery */
int qeth_recover_features(struct net_device *dev)
{
struct qeth_card *card = dev->ml_priv;
netdev_features_t recover = dev->features;

if (recover & NETIF_F_IP_CSUM) {
if (qeth_set_ipa_csum(card, 1, IPA_OUTBOUND_CHECKSUM))
recover ^= NETIF_F_IP_CSUM;
}
if (recover & NETIF_F_RXCSUM) {
if (qeth_set_ipa_csum(card, 1, IPA_INBOUND_CHECKSUM))
recover ^= NETIF_F_RXCSUM;
}
if (recover & NETIF_F_TSO) {
if (qeth_set_ipa_tso(card, 1))
recover ^= NETIF_F_TSO;
}

if (recover == dev->features)
return 0;

dev_warn(&card->gdev->dev,
"Device recovery failed to restore all offload features\n");
dev->features = recover;
return -EIO;
}
EXPORT_SYMBOL_GPL(qeth_recover_features);

int qeth_set_features(struct net_device *dev, netdev_features_t features)
{
struct qeth_card *card = dev->ml_priv;
Expand Down
3 changes: 3 additions & 0 deletions drivers/s390/net/qeth_l2_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1246,6 +1246,9 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
}
/* this also sets saved unicast addresses */
qeth_l2_set_rx_mode(card->dev);
rtnl_lock();
qeth_recover_features(card->dev);
rtnl_unlock();
}
/* let user_space know that device is online */
kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE);
Expand Down
1 change: 1 addition & 0 deletions drivers/s390/net/qeth_l3_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3269,6 +3269,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
else
dev_open(card->dev);
qeth_l3_set_multicast_list(card->dev);
qeth_recover_features(card->dev);
rtnl_unlock();
}
qeth_trace_features(card);
Expand Down

0 comments on commit e830baa

Please sign in to comment.