s390/qeth: rely on kernel for feature recovery
When recovering a device, qeth needs to re-run the IPA commands that enable all previously active HW features. Instead of duplicating qeth_set_features(), let netdev_update_features() recover the missing HW features from dev->wanted_features. Signed-off-by: Julian Wiedmann <jwi@linux.vnet.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
0843c092ee
Коммит
ce34435641
|
@ -998,7 +998,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 *);
|
void qeth_recover_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);
|
||||||
int qeth_vm_request_mac(struct qeth_card *card);
|
int qeth_vm_request_mac(struct qeth_card *card);
|
||||||
int qeth_push_hdr(struct sk_buff *skb, struct qeth_hdr **hdr, unsigned int len);
|
int qeth_push_hdr(struct sk_buff *skb, struct qeth_hdr **hdr, unsigned int len);
|
||||||
|
|
|
@ -6403,32 +6403,29 @@ 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 */
|
#define QETH_HW_FEATURES (NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_TSO)
|
||||||
int qeth_recover_features(struct net_device *dev)
|
|
||||||
|
/**
|
||||||
|
* qeth_recover_features() - Restore device features after recovery
|
||||||
|
* @dev: the recovering net_device
|
||||||
|
*
|
||||||
|
* Caller must hold rtnl lock.
|
||||||
|
*/
|
||||||
|
void qeth_recover_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 recover = dev->features;
|
|
||||||
|
|
||||||
if (recover & NETIF_F_IP_CSUM) {
|
/* force-off any feature that needs an IPA sequence.
|
||||||
if (qeth_set_ipa_csum(card, 1, IPA_OUTBOUND_CHECKSUM))
|
* netdev_update_features() will restart them.
|
||||||
recover ^= NETIF_F_IP_CSUM;
|
*/
|
||||||
}
|
dev->features &= ~QETH_HW_FEATURES;
|
||||||
if (recover & NETIF_F_RXCSUM) {
|
netdev_update_features(dev);
|
||||||
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;
|
|
||||||
|
|
||||||
|
if (features == dev->features)
|
||||||
|
return;
|
||||||
dev_warn(&card->gdev->dev,
|
dev_warn(&card->gdev->dev,
|
||||||
"Device recovery failed to restore all offload features\n");
|
"Device recovery failed to restore all offload features\n");
|
||||||
dev->features = recover;
|
|
||||||
return -EIO;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(qeth_recover_features);
|
EXPORT_SYMBOL_GPL(qeth_recover_features);
|
||||||
|
|
||||||
|
@ -6485,8 +6482,7 @@ netdev_features_t qeth_fix_features(struct net_device *dev,
|
||||||
/* if the card isn't up, remove features that require hw changes */
|
/* if the card isn't up, remove features that require hw changes */
|
||||||
if (card->state == CARD_STATE_DOWN ||
|
if (card->state == CARD_STATE_DOWN ||
|
||||||
card->state == CARD_STATE_RECOVER)
|
card->state == CARD_STATE_RECOVER)
|
||||||
features = features & ~(NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
|
features &= ~QETH_HW_FEATURES;
|
||||||
NETIF_F_TSO);
|
|
||||||
QETH_DBF_HEX(SETUP, 2, &features, sizeof(features));
|
QETH_DBF_HEX(SETUP, 2, &features, sizeof(features));
|
||||||
return features;
|
return features;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче