]> Pileus Git - ~andy/linux/blobdiff - net/mac80211/iface.c
Merge branch 'master' of git://git.infradead.org/users/linville/wireless-next into...
[~andy/linux] / net / mac80211 / iface.c
index 556e7e6ddf0a6b26dda29a33c00ee6c4d0ffed5b..f4350262663f84d2c931ffd589893a91925c0ed0 100644 (file)
@@ -456,21 +456,19 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
                                                 BSS_CHANGED_BEACON_ENABLED);
 
                /* remove beacon */
-               rcu_assign_pointer(sdata->u.ap.beacon, NULL);
+               RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);
                synchronize_rcu();
                kfree(old_beacon);
 
-               /* free all potentially still buffered bcast frames */
-               while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) {
-                       local->total_ps_buffered--;
-                       dev_kfree_skb(skb);
-               }
-
                /* down all dependent devices, that is VLANs */
                list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans,
                                         u.vlan.list)
                        dev_close(vlan->dev);
                WARN_ON(!list_empty(&sdata->u.ap.vlans));
+
+               /* free all potentially still buffered bcast frames */
+               local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps_bc_buf);
+               skb_queue_purge(&sdata->u.ap.ps_bc_buf);
        }
 
        if (going_down)
@@ -645,7 +643,7 @@ static const struct net_device_ops ieee80211_dataif_ops = {
        .ndo_stop               = ieee80211_stop,
        .ndo_uninit             = ieee80211_teardown_sdata,
        .ndo_start_xmit         = ieee80211_subif_start_xmit,
-       .ndo_set_multicast_list = ieee80211_set_multicast_list,
+       .ndo_set_rx_mode        = ieee80211_set_multicast_list,
        .ndo_change_mtu         = ieee80211_change_mtu,
        .ndo_set_mac_address    = ieee80211_change_mac,
        .ndo_select_queue       = ieee80211_netdev_select_queue,
@@ -689,7 +687,7 @@ static const struct net_device_ops ieee80211_monitorif_ops = {
        .ndo_stop               = ieee80211_stop,
        .ndo_uninit             = ieee80211_teardown_sdata,
        .ndo_start_xmit         = ieee80211_monitor_start_xmit,
-       .ndo_set_multicast_list = ieee80211_set_multicast_list,
+       .ndo_set_rx_mode        = ieee80211_set_multicast_list,
        .ndo_change_mtu         = ieee80211_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_select_queue       = ieee80211_monitor_select_queue,
@@ -1214,6 +1212,9 @@ void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata)
        list_del_rcu(&sdata->list);
        mutex_unlock(&sdata->local->iflist_mtx);
 
+       if (ieee80211_vif_is_mesh(&sdata->vif))
+               mesh_path_flush_by_iface(sdata);
+
        synchronize_rcu();
        unregister_netdevice(sdata->dev);
 }
@@ -1233,6 +1234,9 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local)
        list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) {
                list_del(&sdata->list);
 
+               if (ieee80211_vif_is_mesh(&sdata->vif))
+                       mesh_path_flush_by_iface(sdata);
+
                unregister_netdevice_queue(sdata->dev, &unreg_list);
        }
        mutex_unlock(&local->iflist_mtx);