diff options
Diffstat (limited to 'drivers/net/xen-netback/interface.c')
| -rw-r--r-- | drivers/net/xen-netback/interface.c | 84 | 
1 files changed, 15 insertions, 69 deletions
| diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index de569cc19da4..0ca86f9ec4ed 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c @@ -165,69 +165,18 @@ static int xenvif_change_mtu(struct net_device *dev, int mtu)  	return 0;  } -static void xenvif_set_features(struct xenvif *vif) -{ -	struct net_device *dev = vif->dev; -	u32 features = dev->features; - -	if (vif->can_sg) -		features |= NETIF_F_SG; -	if (vif->gso || vif->gso_prefix) -		features |= NETIF_F_TSO; -	if (vif->csum) -		features |= NETIF_F_IP_CSUM; - -	features &= ~(vif->features_disabled); - -	if (!(features & NETIF_F_SG) && dev->mtu > ETH_DATA_LEN) -		dev->mtu = ETH_DATA_LEN; - -	dev->features = features; -} - -static int xenvif_set_tx_csum(struct net_device *dev, u32 data) -{ -	struct xenvif *vif = netdev_priv(dev); -	if (data) { -		if (!vif->csum) -			return -EOPNOTSUPP; -		vif->features_disabled &= ~NETIF_F_IP_CSUM; -	} else { -		vif->features_disabled |= NETIF_F_IP_CSUM; -	} - -	xenvif_set_features(vif); -	return 0; -} - -static int xenvif_set_sg(struct net_device *dev, u32 data) +static u32 xenvif_fix_features(struct net_device *dev, u32 features)  {  	struct xenvif *vif = netdev_priv(dev); -	if (data) { -		if (!vif->can_sg) -			return -EOPNOTSUPP; -		vif->features_disabled &= ~NETIF_F_SG; -	} else { -		vif->features_disabled |= NETIF_F_SG; -	} -	xenvif_set_features(vif); -	return 0; -} +	if (!vif->can_sg) +		features &= ~NETIF_F_SG; +	if (!vif->gso && !vif->gso_prefix) +		features &= ~NETIF_F_TSO; +	if (!vif->csum) +		features &= ~NETIF_F_IP_CSUM; -static int xenvif_set_tso(struct net_device *dev, u32 data) -{ -	struct xenvif *vif = netdev_priv(dev); -	if (data) { -		if (!vif->gso && !vif->gso_prefix) -			return -EOPNOTSUPP; -		vif->features_disabled &= ~NETIF_F_TSO; -	} else { -		vif->features_disabled |= NETIF_F_TSO; -	} - -	xenvif_set_features(vif); -	return 0; +	return features;  }  static const struct xenvif_stat { @@ -274,12 +223,6 @@ static void xenvif_get_strings(struct net_device *dev, u32 stringset, u8 * data)  }  static struct ethtool_ops xenvif_ethtool_ops = { -	.get_tx_csum	= ethtool_op_get_tx_csum, -	.set_tx_csum	= xenvif_set_tx_csum, -	.get_sg		= ethtool_op_get_sg, -	.set_sg		= xenvif_set_sg, -	.get_tso	= ethtool_op_get_tso, -	.set_tso	= xenvif_set_tso,  	.get_link	= ethtool_op_get_link,  	.get_sset_count = xenvif_get_sset_count, @@ -293,6 +236,7 @@ static struct net_device_ops xenvif_netdev_ops = {  	.ndo_open	= xenvif_open,  	.ndo_stop	= xenvif_close,  	.ndo_change_mtu	= xenvif_change_mtu, +	.ndo_fix_features = xenvif_fix_features,  };  struct xenvif *xenvif_alloc(struct device *parent, domid_t domid, @@ -331,7 +275,8 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,  	vif->credit_timeout.expires = jiffies;  	dev->netdev_ops	= &xenvif_netdev_ops; -	xenvif_set_features(vif); +	dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO; +	dev->features = dev->hw_features;  	SET_ETHTOOL_OPS(dev, &xenvif_ethtool_ops);  	dev->tx_queue_len = XENVIF_QUEUE_LENGTH; @@ -367,8 +312,6 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref,  	if (vif->irq)  		return 0; -	xenvif_set_features(vif); -  	err = xen_netbk_map_frontend_rings(vif, tx_ring_ref, rx_ring_ref);  	if (err < 0)  		goto err; @@ -384,9 +327,12 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref,  	xenvif_get(vif);  	rtnl_lock(); -	netif_carrier_on(vif->dev);  	if (netif_running(vif->dev))  		xenvif_up(vif); +	if (!vif->can_sg && vif->dev->mtu > ETH_DATA_LEN) +		dev_set_mtu(vif->dev, ETH_DATA_LEN); +	netdev_update_features(vif->dev); +	netif_carrier_on(vif->dev);  	rtnl_unlock();  	return 0; |