Merge remote-tracking branch 'lightnvm/for-next'
[deliverable/linux.git] / drivers / net / ethernet / intel / igb / igb_main.c
index 942a89fb009088619936ea8e3ad909287d76ceca..af75eac5fa1652f7cf820259d9f262e2c0498931 100644 (file)
@@ -176,6 +176,8 @@ static int igb_ndo_set_vf_spoofchk(struct net_device *netdev, int vf,
 static int igb_ndo_get_vf_config(struct net_device *netdev, int vf,
                                 struct ifla_vf_info *ivi);
 static void igb_check_vf_rate_limit(struct igb_adapter *);
+static void igb_nfc_filter_exit(struct igb_adapter *adapter);
+static void igb_nfc_filter_restore(struct igb_adapter *adapter);
 
 #ifdef CONFIG_PCI_IOV
 static int igb_vf_configure(struct igb_adapter *adapter, int vf);
@@ -1611,6 +1613,7 @@ static void igb_configure(struct igb_adapter *adapter)
        igb_setup_mrqc(adapter);
        igb_setup_rctl(adapter);
 
+       igb_nfc_filter_restore(adapter);
        igb_configure_tx(adapter);
        igb_configure_rx(adapter);
 
@@ -2059,6 +2062,21 @@ static int igb_set_features(struct net_device *netdev,
        if (!(changed & (NETIF_F_RXALL | NETIF_F_NTUPLE)))
                return 0;
 
+       if (!(features & NETIF_F_NTUPLE)) {
+               struct hlist_node *node2;
+               struct igb_nfc_filter *rule;
+
+               spin_lock(&adapter->nfc_lock);
+               hlist_for_each_entry_safe(rule, node2,
+                                         &adapter->nfc_filter_list, nfc_node) {
+                       igb_erase_filter(adapter, rule);
+                       hlist_del(&rule->nfc_node);
+                       kfree(rule);
+               }
+               spin_unlock(&adapter->nfc_lock);
+               adapter->nfc_filter_count = 0;
+       }
+
        netdev->features = features;
 
        if (netif_running(netdev))
@@ -3053,6 +3071,7 @@ static int igb_sw_init(struct igb_adapter *adapter)
                                  VLAN_HLEN;
        adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
 
+       spin_lock_init(&adapter->nfc_lock);
        spin_lock_init(&adapter->stats64_lock);
 #ifdef CONFIG_PCI_IOV
        switch (hw->mac.type) {
@@ -3240,6 +3259,8 @@ static int __igb_close(struct net_device *netdev, bool suspending)
        igb_down(adapter);
        igb_free_irq(adapter);
 
+       igb_nfc_filter_exit(adapter);
+
        igb_free_all_tx_resources(adapter);
        igb_free_all_rx_resources(adapter);
 
@@ -8306,4 +8327,28 @@ int igb_reinit_queues(struct igb_adapter *adapter)
 
        return err;
 }
+
+static void igb_nfc_filter_exit(struct igb_adapter *adapter)
+{
+       struct igb_nfc_filter *rule;
+
+       spin_lock(&adapter->nfc_lock);
+
+       hlist_for_each_entry(rule, &adapter->nfc_filter_list, nfc_node)
+               igb_erase_filter(adapter, rule);
+
+       spin_unlock(&adapter->nfc_lock);
+}
+
+static void igb_nfc_filter_restore(struct igb_adapter *adapter)
+{
+       struct igb_nfc_filter *rule;
+
+       spin_lock(&adapter->nfc_lock);
+
+       hlist_for_each_entry(rule, &adapter->nfc_filter_list, nfc_node)
+               igb_add_filter(adapter, rule);
+
+       spin_unlock(&adapter->nfc_lock);
+}
 /* igb_main.c */
This page took 0.02621 seconds and 5 git commands to generate.