]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - net/mac80211/rx.c
Merge tag 'mac80211-next-for-davem-2015-04-10' of git://git.kernel.org/pub/scm/linux...
[karo-tx-linux.git] / net / mac80211 / rx.c
index 2cd02278d4d4076c580f9253460ce98f677edfe1..260eed45b6d2ff105052643169465c04d333c182 100644 (file)
@@ -1185,6 +1185,7 @@ static void sta_ps_start(struct sta_info *sta)
        struct ieee80211_sub_if_data *sdata = sta->sdata;
        struct ieee80211_local *local = sdata->local;
        struct ps_data *ps;
+       int tid;
 
        if (sta->sdata->vif.type == NL80211_IFTYPE_AP ||
            sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
@@ -1198,6 +1199,18 @@ static void sta_ps_start(struct sta_info *sta)
                drv_sta_notify(local, sdata, STA_NOTIFY_SLEEP, &sta->sta);
        ps_dbg(sdata, "STA %pM aid %d enters power save mode\n",
               sta->sta.addr, sta->sta.aid);
+
+       if (!sta->sta.txq[0])
+               return;
+
+       for (tid = 0; tid < ARRAY_SIZE(sta->sta.txq); tid++) {
+               struct txq_info *txqi = to_txq_info(sta->sta.txq[tid]);
+
+               if (!skb_queue_len(&txqi->queue))
+                       set_bit(tid, &sta->txq_buffered_tids);
+               else
+                       clear_bit(tid, &sta->txq_buffered_tids);
+       }
 }
 
 static void sta_ps_end(struct sta_info *sta)
@@ -3424,7 +3437,8 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
        __le16 fc;
        struct ieee80211_rx_data rx;
        struct ieee80211_sub_if_data *prev;
-       struct sta_info *sta, *tmp, *prev_sta;
+       struct sta_info *sta, *prev_sta;
+       struct rhash_head *tmp;
        int err = 0;
 
        fc = ((struct ieee80211_hdr *)skb->data)->frame_control;
@@ -3459,9 +3473,13 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
                ieee80211_scan_rx(local, skb);
 
        if (ieee80211_is_data(fc)) {
+               const struct bucket_table *tbl;
+
                prev_sta = NULL;
 
-               for_each_sta_info(local, hdr->addr2, sta, tmp) {
+               tbl = rht_dereference_rcu(local->sta_hash.tbl, &local->sta_hash);
+
+               for_each_sta_info(local, tbl, hdr->addr2, sta, tmp) {
                        if (!prev_sta) {
                                prev_sta = sta;
                                continue;