소스 검색

Merge branch 'vlan_offloads'

Vlad Yasevich says:

====================
Audit all drivers for correct vlan_features.

Some drivers set vlan acceleration features in vlan_features.  This causes
issues with Q-in-Q/802.1ad configurations.

Audit all the drivers for correct vlan_features.  Fix broken ones.
Add a warning to vlan code to help catch future offenders.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
David S. Miller 11 년 전
부모
커밋
5f2feca20e
5개의 변경된 파일19개의 추가작업 그리고 3개의 파일을 삭제
  1. 3 1
      drivers/net/ethernet/qlogic/qlge/qlge_main.c
  2. 2 1
      drivers/net/ifb.c
  3. 4 1
      drivers/net/veth.c
  4. 7 0
      include/linux/netdev_features.h
  5. 3 0
      net/8021q/vlan_dev.c

+ 3 - 1
drivers/net/ethernet/qlogic/qlge/qlge_main.c

@@ -4765,7 +4765,9 @@ static int qlge_probe(struct pci_dev *pdev,
 	ndev->features = ndev->hw_features;
 	ndev->features = ndev->hw_features;
 	ndev->vlan_features = ndev->hw_features;
 	ndev->vlan_features = ndev->hw_features;
 	/* vlan gets same features (except vlan filter) */
 	/* vlan gets same features (except vlan filter) */
-	ndev->vlan_features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
+	ndev->vlan_features &= ~(NETIF_F_HW_VLAN_CTAG_FILTER |
+				 NETIF_F_HW_VLAN_CTAG_TX |
+				 NETIF_F_HW_VLAN_CTAG_RX);
 
 
 	if (test_bit(QL_DMA64, &qdev->flags))
 	if (test_bit(QL_DMA64, &qdev->flags))
 		ndev->features |= NETIF_F_HIGHDMA;
 		ndev->features |= NETIF_F_HIGHDMA;

+ 2 - 1
drivers/net/ifb.c

@@ -180,7 +180,8 @@ static void ifb_setup(struct net_device *dev)
 	dev->tx_queue_len = TX_Q_LIMIT;
 	dev->tx_queue_len = TX_Q_LIMIT;
 
 
 	dev->features |= IFB_FEATURES;
 	dev->features |= IFB_FEATURES;
-	dev->vlan_features |= IFB_FEATURES;
+	dev->vlan_features |= IFB_FEATURES & ~(NETIF_F_HW_VLAN_CTAG_TX |
+					       NETIF_F_HW_VLAN_STAG_TX);
 
 
 	dev->flags |= IFF_NOARP;
 	dev->flags |= IFF_NOARP;
 	dev->flags &= ~IFF_MULTICAST;
 	dev->flags &= ~IFF_MULTICAST;

+ 4 - 1
drivers/net/veth.c

@@ -286,7 +286,10 @@ static void veth_setup(struct net_device *dev)
 	dev->features |= NETIF_F_LLTX;
 	dev->features |= NETIF_F_LLTX;
 	dev->features |= VETH_FEATURES;
 	dev->features |= VETH_FEATURES;
 	dev->vlan_features = dev->features &
 	dev->vlan_features = dev->features &
-			     ~(NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX);
+			     ~(NETIF_F_HW_VLAN_CTAG_TX |
+			       NETIF_F_HW_VLAN_STAG_TX |
+			       NETIF_F_HW_VLAN_CTAG_RX |
+			       NETIF_F_HW_VLAN_STAG_RX);
 	dev->destructor = veth_dev_free;
 	dev->destructor = veth_dev_free;
 
 
 	dev->hw_features = VETH_FEATURES;
 	dev->hw_features = VETH_FEATURES;

+ 7 - 0
include/linux/netdev_features.h

@@ -163,4 +163,11 @@ enum {
 /* changeable features with no special hardware requirements */
 /* changeable features with no special hardware requirements */
 #define NETIF_F_SOFT_FEATURES	(NETIF_F_GSO | NETIF_F_GRO)
 #define NETIF_F_SOFT_FEATURES	(NETIF_F_GSO | NETIF_F_GRO)
 
 
+#define NETIF_F_VLAN_FEATURES	(NETIF_F_HW_VLAN_CTAG_FILTER | \
+				 NETIF_F_HW_VLAN_CTAG_RX | \
+				 NETIF_F_HW_VLAN_CTAG_TX | \
+				 NETIF_F_HW_VLAN_STAG_FILTER | \
+				 NETIF_F_HW_VLAN_STAG_RX | \
+				 NETIF_F_HW_VLAN_STAG_TX)
+
 #endif	/* _LINUX_NETDEV_FEATURES_H */
 #endif	/* _LINUX_NETDEV_FEATURES_H */

+ 3 - 0
net/8021q/vlan_dev.c

@@ -578,6 +578,9 @@ static int vlan_dev_init(struct net_device *dev)
 
 
 	dev->features |= real_dev->vlan_features | NETIF_F_LLTX;
 	dev->features |= real_dev->vlan_features | NETIF_F_LLTX;
 	dev->gso_max_size = real_dev->gso_max_size;
 	dev->gso_max_size = real_dev->gso_max_size;
+	if (dev->features & NETIF_F_VLAN_FEATURES)
+		netdev_warn(real_dev, "VLAN features are set incorrectly.  Q-in-Q configurations may not work correctly.\n");
+
 
 
 	/* ipv6 shared card related stuff */
 	/* ipv6 shared card related stuff */
 	dev->dev_id = real_dev->dev_id;
 	dev->dev_id = real_dev->dev_id;