s390/qeth: consistently re-enable device features

commit e830baa9c3 ("qeth: restore device features after recovery") and
commit ce34435641 ("s390/qeth: rely on kernel for feature recovery")
made sure that the HW functions for device features get re-programmed
after recovery.

But we missed that the same handling is also required when a card is
first set offline (destroying all HW context), and then online again.
Fix this by moving the re-enable action out of the recovery-only path.

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Julian Wiedmann 2018-06-29 19:45:54 +02:00 committed by David S. Miller
parent ce28867fd2
commit d025da9eb1
4 changed files with 16 additions and 17 deletions

View File

@ -1040,7 +1040,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);
void qeth_recover_features(struct net_device *dev); void qeth_enable_hw_features(struct net_device *dev);
netdev_features_t qeth_fix_features(struct net_device *, netdev_features_t); netdev_features_t qeth_fix_features(struct net_device *, netdev_features_t);
netdev_features_t qeth_features_check(struct sk_buff *skb, netdev_features_t qeth_features_check(struct sk_buff *skb,
struct net_device *dev, struct net_device *dev,

View File

@ -6469,28 +6469,27 @@ static int qeth_set_ipa_rx_csum(struct qeth_card *card, bool on)
#define QETH_HW_FEATURES (NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_TSO | \ #define QETH_HW_FEATURES (NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_TSO | \
NETIF_F_IPV6_CSUM) NETIF_F_IPV6_CSUM)
/** /**
* qeth_recover_features() - Restore device features after recovery * qeth_enable_hw_features() - (Re-)Enable HW functions for device features
* @dev: the recovering net_device * @dev: a net_device
*
* Caller must hold rtnl lock.
*/ */
void qeth_recover_features(struct net_device *dev) void qeth_enable_hw_features(struct net_device *dev)
{ {
netdev_features_t features = dev->features;
struct qeth_card *card = dev->ml_priv; struct qeth_card *card = dev->ml_priv;
netdev_features_t features;
rtnl_lock();
features = dev->features;
/* force-off any feature that needs an IPA sequence. /* force-off any feature that needs an IPA sequence.
* netdev_update_features() will restart them. * netdev_update_features() will restart them.
*/ */
dev->features &= ~QETH_HW_FEATURES; dev->features &= ~QETH_HW_FEATURES;
netdev_update_features(dev); netdev_update_features(dev);
if (features != dev->features)
if (features == dev->features) dev_warn(&card->gdev->dev,
return; "Device recovery failed to restore all offload features\n");
dev_warn(&card->gdev->dev, rtnl_unlock();
"Device recovery failed to restore all offload features\n");
} }
EXPORT_SYMBOL_GPL(qeth_recover_features); EXPORT_SYMBOL_GPL(qeth_enable_hw_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)
{ {

View File

@ -1119,6 +1119,8 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
netif_carrier_off(card->dev); netif_carrier_off(card->dev);
qeth_set_allowed_threads(card, 0xffffffff, 0); qeth_set_allowed_threads(card, 0xffffffff, 0);
qeth_enable_hw_features(card->dev);
if (recover_flag == CARD_STATE_RECOVER) { if (recover_flag == CARD_STATE_RECOVER) {
if (recovery_mode && if (recovery_mode &&
card->info.type != QETH_CARD_TYPE_OSN) { card->info.type != QETH_CARD_TYPE_OSN) {
@ -1130,9 +1132,6 @@ 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);

View File

@ -2662,6 +2662,8 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
netif_carrier_on(card->dev); netif_carrier_on(card->dev);
else else
netif_carrier_off(card->dev); netif_carrier_off(card->dev);
qeth_enable_hw_features(card->dev);
if (recover_flag == CARD_STATE_RECOVER) { if (recover_flag == CARD_STATE_RECOVER) {
rtnl_lock(); rtnl_lock();
if (recovery_mode) if (recovery_mode)
@ -2669,7 +2671,6 @@ 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_rx_mode(card->dev); qeth_l3_set_rx_mode(card->dev);
qeth_recover_features(card->dev);
rtnl_unlock(); rtnl_unlock();
} }
qeth_trace_features(card); qeth_trace_features(card);