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

Commit 5fb13570 authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller
Browse files

[VLAN]: Propagate selected feature bits to VLAN devices



Propagate feature bits from the NETDEV_FEAT_CHANGE notifier. For now
only TSO is propagated for devices that announce their ability to
support TSO in combination with VLAN accel by setting the NETIF_F_VLAN_TSO
flag.

Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7ff6e6f7
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -514,10 +514,12 @@ struct net_device
#define NETIF_F_NETNS_LOCAL	8192	/* Does not change network namespaces */
#define NETIF_F_MULTI_QUEUE	16384	/* Has multiple TX/RX queues */
#define NETIF_F_LRO		32768	/* large receive offload */
#define NETIF_F_VLAN_TSO	65536	/* Supports TSO for VLANs */
#define NETIF_F_VLAN_CSUM	131072	/* Supports TX checksumming for VLANs */

	/* Segmentation offload features */
#define NETIF_F_GSO_SHIFT	16
#define NETIF_F_GSO_MASK	0xffff0000
#define NETIF_F_GSO_SHIFT	20
#define NETIF_F_GSO_MASK	0xfff00000
#define NETIF_F_TSO		(SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT)
#define NETIF_F_UFO		(SKB_GSO_UDP << NETIF_F_GSO_SHIFT)
#define NETIF_F_GSO_ROBUST	(SKB_GSO_DODGY << NETIF_F_GSO_SHIFT)
+30 −0
Original line number Diff line number Diff line
@@ -382,6 +382,24 @@ static void vlan_sync_address(struct net_device *dev,
	memcpy(vlan->real_dev_addr, dev->dev_addr, ETH_ALEN);
}

static void vlan_transfer_features(struct net_device *dev,
				   struct net_device *vlandev)
{
	unsigned long old_features = vlandev->features;

	if (dev->features & NETIF_F_VLAN_TSO) {
		vlandev->features &= ~VLAN_TSO_FEATURES;
		vlandev->features |= dev->features & VLAN_TSO_FEATURES;
	}
	if (dev->features & NETIF_F_VLAN_CSUM) {
		vlandev->features &= ~NETIF_F_ALL_CSUM;
		vlandev->features |= dev->features & NETIF_F_ALL_CSUM;
	}

	if (old_features != vlandev->features)
		netdev_features_change(vlandev);
}

static void __vlan_device_event(struct net_device *dev, unsigned long event)
{
	switch (event) {
@@ -448,6 +466,18 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
		}
		break;

	case NETDEV_FEAT_CHANGE:
		/* Propagate device features to underlying device */
		for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
			vlandev = vlan_group_get_device(grp, i);
			if (!vlandev)
				continue;

			vlan_transfer_features(dev, vlandev);
		}

		break;

	case NETDEV_DOWN:
		/* Put all VLANs for this dev in the down state too.  */
		for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
+2 −0
Original line number Diff line number Diff line
@@ -7,6 +7,8 @@
#define VLAN_GRP_HASH_SIZE	(1 << VLAN_GRP_HASH_SHIFT)
#define VLAN_GRP_HASH_MASK	(VLAN_GRP_HASH_SIZE - 1)

#define VLAN_TSO_FEATURES	(NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_SG)

/*  Find a VLAN device by the MAC address of its Ethernet device, and
 *  it's VLAN ID.  The default configuration is to have VLAN's scope
 *  to be box-wide, so the MAC will be ignored.  The mac will only be
+5 −0
Original line number Diff line number Diff line
@@ -663,6 +663,11 @@ static int vlan_dev_init(struct net_device *dev)
					  (1<<__LINK_STATE_DORMANT))) |
		      (1<<__LINK_STATE_PRESENT);

	if (real_dev->features & NETIF_F_VLAN_TSO)
		dev->features |= real_dev->features & VLAN_TSO_FEATURES;
	if (real_dev->features & NETIF_F_VLAN_CSUM)
		dev->features |= real_dev->features & NETIF_F_ALL_CSUM;

	/* ipv6 shared card related stuff */
	dev->dev_id = real_dev->dev_id;