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

Commit fb507934 authored by Michał Mirosław's avatar Michał Mirosław Committed by David S. Miller
Browse files

net: convert xen-netfront to hw_features



Not tested in any way. The original code for offload setting seems broken
as it resets the features on every netback reconnect.

This will set GSO_ROBUST at device creation time (earlier than connect time).

RX checksum offload is forced on - so advertise as it is.

Signed-off-by: default avatarMichał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 78e47fe4
Loading
Loading
Loading
Loading
+23 −34
Original line number Diff line number Diff line
@@ -1148,6 +1148,8 @@ static const struct net_device_ops xennet_netdev_ops = {
	.ndo_change_mtu	     = xennet_change_mtu,
	.ndo_set_mac_address = eth_mac_addr,
	.ndo_validate_addr   = eth_validate_addr,
	.ndo_fix_features    = xennet_fix_features,
	.ndo_set_features    = xennet_set_features,
};

static struct net_device * __devinit xennet_create_dev(struct xenbus_device *dev)
@@ -1209,7 +1211,9 @@ static struct net_device * __devinit xennet_create_dev(struct xenbus_device *dev
	netdev->netdev_ops	= &xennet_netdev_ops;

	netif_napi_add(netdev, &np->napi, xennet_poll, 64);
	netdev->features        = NETIF_F_IP_CSUM;
	netdev->features        = NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
				  NETIF_F_GSO_ROBUST;
	netdev->hw_features	= NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO;

	SET_ETHTOOL_OPS(netdev, &xennet_ethtool_ops);
	SET_NETDEV_DEV(netdev, &dev->dev);
@@ -1509,52 +1513,40 @@ static int talk_to_netback(struct xenbus_device *dev,
	return err;
}

static int xennet_set_sg(struct net_device *dev, u32 data)
static u32 xennet_fix_features(struct net_device *dev, u32 features)
{
	if (data) {
	struct netfront_info *np = netdev_priv(dev);
	int val;

	if (features & NETIF_F_SG) {
		if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, "feature-sg",
				 "%d", &val) < 0)
			val = 0;
		if (!val)
			return -ENOSYS;
	} else if (dev->mtu > ETH_DATA_LEN)
		dev->mtu = ETH_DATA_LEN;

	return ethtool_op_set_sg(dev, data);
		if (!val)
			features &= ~NETIF_F_SG;
	}

static int xennet_set_tso(struct net_device *dev, u32 data)
{
	if (data) {
		struct netfront_info *np = netdev_priv(dev);
		int val;

	if (features & NETIF_F_TSO) {
		if (xenbus_scanf(XBT_NIL, np->xbdev->otherend,
				 "feature-gso-tcpv4", "%d", &val) < 0)
			val = 0;

		if (!val)
			return -ENOSYS;
			features &= ~NETIF_F_TSO;
	}

	return ethtool_op_set_tso(dev, data);
	return features;
}

static void xennet_set_features(struct net_device *dev)
static int xennet_set_features(struct net_device *dev, u32 features)
{
	/* Turn off all GSO bits except ROBUST. */
	dev->features &= ~NETIF_F_GSO_MASK;
	dev->features |= NETIF_F_GSO_ROBUST;
	xennet_set_sg(dev, 0);

	/* We need checksum offload to enable scatter/gather and TSO. */
	if (!(dev->features & NETIF_F_IP_CSUM))
		return;
	if (!(features & NETIF_F_SG) && dev->mtu > ETH_DATA_LEN) {
		netdev_info(dev, "Reducing MTU because no SG offload");
		dev->mtu = ETH_DATA_LEN;
	}

	if (!xennet_set_sg(dev, 1))
		xennet_set_tso(dev, 1);
	return 0;
}

static int xennet_connect(struct net_device *dev)
@@ -1581,7 +1573,7 @@ static int xennet_connect(struct net_device *dev)
	if (err)
		return err;

	xennet_set_features(dev);
	netdev_update_features(dev);

	spin_lock_bh(&np->rx_lock);
	spin_lock_irq(&np->tx_lock);
@@ -1709,9 +1701,6 @@ static void xennet_get_strings(struct net_device *dev, u32 stringset, u8 * data)

static const struct ethtool_ops xennet_ethtool_ops =
{
	.set_tx_csum = ethtool_op_set_tx_csum,
	.set_sg = xennet_set_sg,
	.set_tso = xennet_set_tso,
	.get_link = ethtool_op_get_link,

	.get_sset_count = xennet_get_sset_count,