atl1: do vlan cleanup

- unify vlan and nonvlan rx path
- kill adapter->vlgrp and atlx_vlan_rx_register
- allow to turn on/off rx/tx vlan accel via ethtool (set_features)

Signed-off-by: Jiri Pirko <jpirko@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/drivers/net/atlx/atlx.c b/drivers/net/atlx/atlx.c
index afb7f7d..aabcf4b 100644
--- a/drivers/net/atlx/atlx.c
+++ b/drivers/net/atlx/atlx.c
@@ -211,8 +211,18 @@
 	spin_unlock_irqrestore(&adapter->lock, flags);
 }
 
-static void atlx_vlan_rx_register(struct net_device *netdev,
-	struct vlan_group *grp)
+static void __atlx_vlan_mode(u32 features, u32 *ctrl)
+{
+	if (features & NETIF_F_HW_VLAN_RX) {
+		/* enable VLAN tag insert/strip */
+		*ctrl |= MAC_CTRL_RMV_VLAN;
+	} else {
+		/* disable VLAN tag insert/strip */
+		*ctrl &= ~MAC_CTRL_RMV_VLAN;
+	}
+}
+
+static void atlx_vlan_mode(struct net_device *netdev, u32 features)
 {
 	struct atlx_adapter *adapter = netdev_priv(netdev);
 	unsigned long flags;
@@ -220,27 +230,40 @@
 
 	spin_lock_irqsave(&adapter->lock, flags);
 	/* atlx_irq_disable(adapter); FIXME: confirm/remove */
-	adapter->vlgrp = grp;
-
-	if (grp) {
-		/* enable VLAN tag insert/strip */
-		ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL);
-		ctrl |= MAC_CTRL_RMV_VLAN;
-		iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL);
-	} else {
-		/* disable VLAN tag insert/strip */
-		ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL);
-		ctrl &= ~MAC_CTRL_RMV_VLAN;
-		iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL);
-	}
-
+	ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL);
+	__atlx_vlan_mode(features, &ctrl);
+	iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL);
 	/* atlx_irq_enable(adapter); FIXME */
 	spin_unlock_irqrestore(&adapter->lock, flags);
 }
 
 static void atlx_restore_vlan(struct atlx_adapter *adapter)
 {
-	atlx_vlan_rx_register(adapter->netdev, adapter->vlgrp);
+	atlx_vlan_mode(adapter->netdev, adapter->netdev->features);
+}
+
+static u32 atlx_fix_features(struct net_device *netdev, u32 features)
+{
+	/*
+	 * Since there is no support for separate rx/tx vlan accel
+	 * enable/disable make sure tx flag is always in same state as rx.
+	 */
+	if (features & NETIF_F_HW_VLAN_RX)
+		features |= NETIF_F_HW_VLAN_TX;
+	else
+		features &= ~NETIF_F_HW_VLAN_TX;
+
+	return features;
+}
+
+static int atlx_set_features(struct net_device *netdev, u32 features)
+{
+	u32 changed = netdev->features ^ features;
+
+	if (changed & NETIF_F_HW_VLAN_RX)
+		atlx_vlan_mode(netdev, features);
+
+	return 0;
 }
 
 #endif /* ATLX_C */