Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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 */
+29 −0
Original line number Diff line number Diff line
@@ -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;
+3 −0
Original line number Diff line number Diff line
@@ -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);
+1 −0
Original line number Diff line number Diff line
@@ -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);