Commit e830baa9 authored by Hans Wippel's avatar Hans Wippel Committed by David S. Miller

qeth: restore device features after recovery

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: default avatarHans Wippel <hwippel@linux.vnet.ibm.com>
Signed-off-by: default avatarUrsula Braun <ubraun@linux.vnet.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent bc6c03fa
...@@ -999,6 +999,7 @@ struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *, ...@@ -999,6 +999,7 @@ struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *,
__u16, __u16, __u16, __u16,
enum qeth_prot_versions); enum qeth_prot_versions);
int qeth_set_features(struct net_device *, netdev_features_t); 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); netdev_features_t qeth_fix_features(struct net_device *, netdev_features_t);
/* exports for OSN */ /* exports for OSN */
......
...@@ -6131,6 +6131,35 @@ static int qeth_set_ipa_tso(struct qeth_card *card, int on) ...@@ -6131,6 +6131,35 @@ static int qeth_set_ipa_tso(struct qeth_card *card, int on)
return rc; 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) int qeth_set_features(struct net_device *dev, netdev_features_t features)
{ {
struct qeth_card *card = dev->ml_priv; struct qeth_card *card = dev->ml_priv;
......
...@@ -1246,6 +1246,9 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) ...@@ -1246,6 +1246,9 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
} }
/* this also sets saved unicast addresses */ /* this also sets saved unicast addresses */
qeth_l2_set_rx_mode(card->dev); qeth_l2_set_rx_mode(card->dev);
rtnl_lock();
qeth_recover_features(card->dev);
rtnl_unlock();
} }
/* let user_space know that device is online */ /* let user_space know that device is online */
kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE);
......
...@@ -3269,6 +3269,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) ...@@ -3269,6 +3269,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
else else
dev_open(card->dev); dev_open(card->dev);
qeth_l3_set_multicast_list(card->dev); qeth_l3_set_multicast_list(card->dev);
qeth_recover_features(card->dev);
rtnl_unlock(); rtnl_unlock();
} }
qeth_trace_features(card); qeth_trace_features(card);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment