i2c: i801: Add DeviceIDs for SunrisePoint LP
[pandora-kernel.git] / net / mac80211 / sta_info.c
index 8eaa746..1914f5a 100644 (file)
@@ -73,7 +73,7 @@ static int sta_info_hash_del(struct ieee80211_local *local,
        if (!s)
                return -ENOENT;
        if (s == sta) {
-               RCU_INIT_POINTER(local->sta_hash[STA_HASH(sta->sta.addr)],
+               rcu_assign_pointer(local->sta_hash[STA_HASH(sta->sta.addr)],
                                   s->hnext);
                return 0;
        }
@@ -83,7 +83,7 @@ static int sta_info_hash_del(struct ieee80211_local *local,
                s = rcu_dereference_protected(s->hnext,
                                        lockdep_is_held(&local->sta_lock));
        if (rcu_access_pointer(s->hnext)) {
-               RCU_INIT_POINTER(s->hnext, sta->hnext);
+               rcu_assign_pointer(s->hnext, sta->hnext);
                return 0;
        }
 
@@ -232,7 +232,7 @@ static void sta_info_hash_add(struct ieee80211_local *local,
                              struct sta_info *sta)
 {
        sta->hnext = local->sta_hash[STA_HASH(sta->sta.addr)];
-       RCU_INIT_POINTER(local->sta_hash[STA_HASH(sta->sta.addr)], sta);
+       rcu_assign_pointer(local->sta_hash[STA_HASH(sta->sta.addr)], sta);
 }
 
 static void sta_unblock(struct work_struct *wk)
@@ -292,6 +292,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
                return NULL;
 
        spin_lock_init(&sta->lock);
+       spin_lock_init(&sta->ps_lock);
        INIT_WORK(&sta->drv_unblock_wk, sta_unblock);
        INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work);
        mutex_init(&sta->ampdu_mlme.mtx);
@@ -1021,7 +1022,7 @@ void sta_info_init(struct ieee80211_local *local)
 
 void sta_info_stop(struct ieee80211_local *local)
 {
-       del_timer(&local->sta_cleanup);
+       del_timer_sync(&local->sta_cleanup);
        sta_info_flush(local, NULL);
 }
 
@@ -1129,6 +1130,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
        struct ieee80211_local *local = sdata->local;
        struct sk_buff_head pending;
        int filtered = 0, buffered = 0, ac;
+       unsigned long flags;
 
        clear_sta_flag(sta, WLAN_STA_SP);
 
@@ -1140,21 +1142,28 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
 
        skb_queue_head_init(&pending);
 
+       /* sync with ieee80211_tx_h_unicast_ps_buf */
+       spin_lock(&sta->ps_lock);
        /* Send all buffered frames to the station */
        for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
                int count = skb_queue_len(&pending), tmp;
 
+               spin_lock_irqsave(&sta->tx_filtered[ac].lock, flags);
                skb_queue_splice_tail_init(&sta->tx_filtered[ac], &pending);
+               spin_unlock_irqrestore(&sta->tx_filtered[ac].lock, flags);
                tmp = skb_queue_len(&pending);
                filtered += tmp - count;
                count = tmp;
 
+               spin_lock_irqsave(&sta->ps_tx_buf[ac].lock, flags);
                skb_queue_splice_tail_init(&sta->ps_tx_buf[ac], &pending);
+               spin_unlock_irqrestore(&sta->ps_tx_buf[ac].lock, flags);
                tmp = skb_queue_len(&pending);
                buffered += tmp - count;
        }
 
        ieee80211_add_pending_skbs_fn(local, &pending, clear_sta_ps_flags, sta);
+       spin_unlock(&sta->ps_lock);
 
        local->total_ps_buffered -= buffered;
 
@@ -1202,6 +1211,7 @@ static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata,
        memcpy(nullfunc->addr1, sta->sta.addr, ETH_ALEN);
        memcpy(nullfunc->addr2, sdata->vif.addr, ETH_ALEN);
        memcpy(nullfunc->addr3, sdata->vif.addr, ETH_ALEN);
+       nullfunc->seq_ctrl = 0;
 
        skb->priority = tid;
        skb_set_queue_mapping(skb, ieee802_1d_to_ac[tid]);