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: Hans Wippel <hwippel@linux.vnet.ibm.com> Signed-off-by: Ursula Braun <ubraun@linux.vnet.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
bc6c03fa3c
commit
e830baa9c3
4 changed files with 34 additions and 0 deletions
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue