]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/mac80211/iface.c
Merge tag 'stable/for-linus-3.9-rc0-tag' of git://git.kernel.org/pub/scm/linux/kernel...
[karo-tx-linux.git] / net / mac80211 / iface.c
index e9223ce2bf994a4a9b4db60bcf15219eb5390528..2c059e54e88575bf1364a17b9a9bc2f020c5a7a6 100644 (file)
@@ -294,7 +294,8 @@ static int ieee80211_check_queues(struct ieee80211_sub_if_data *sdata)
                }
        }
 
-       if ((sdata->vif.type != NL80211_IFTYPE_AP) ||
+       if ((sdata->vif.type != NL80211_IFTYPE_AP &&
+            sdata->vif.type != NL80211_IFTYPE_MESH_POINT) ||
            !(sdata->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)) {
                sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE;
                return 0;
@@ -680,6 +681,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
        struct sk_buff *skb, *tmp;
        u32 hw_reconf_flags = 0;
        int i, flushed;
+       struct ps_data *ps;
 
        clear_bit(SDATA_STATE_RUNNING, &sdata->state);
 
@@ -694,6 +696,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
 
        ieee80211_roc_purge(sdata);
 
+       if (sdata->vif.type == NL80211_IFTYPE_STATION)
+               ieee80211_mgd_stop(sdata);
+
        /*
         * Remove all stations associated with this interface.
         *
@@ -768,8 +773,19 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
                                         u.vlan.list)
                        dev_close(vlan->dev);
                WARN_ON(!list_empty(&sdata->u.ap.vlans));
-       } else if (sdata->vif.type == NL80211_IFTYPE_STATION) {
-               ieee80211_mgd_stop(sdata);
+       } else if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
+               /* remove all packets in parent bc_buf pointing to this dev */
+               ps = &sdata->bss->ps;
+
+               spin_lock_irqsave(&ps->bc_buf.lock, flags);
+               skb_queue_walk_safe(&ps->bc_buf, skb, tmp) {
+                       if (skb->dev == sdata->dev) {
+                               __skb_unlink(skb, &ps->bc_buf);
+                               local->total_ps_buffered--;
+                               ieee80211_free_txskb(&local->hw, skb);
+                       }
+               }
+               spin_unlock_irqrestore(&ps->bc_buf.lock, flags);
        }
 
        if (going_down)