|
@@ -330,6 +330,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
|
|
|
rcu_read_unlock();
|
|
rcu_read_unlock();
|
|
|
|
|
|
|
|
spin_lock_init(&sta->lock);
|
|
spin_lock_init(&sta->lock);
|
|
|
|
|
+ spin_lock_init(&sta->ps_lock);
|
|
|
INIT_WORK(&sta->drv_unblock_wk, sta_unblock);
|
|
INIT_WORK(&sta->drv_unblock_wk, sta_unblock);
|
|
|
INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work);
|
|
INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work);
|
|
|
mutex_init(&sta->ampdu_mlme.mtx);
|
|
mutex_init(&sta->ampdu_mlme.mtx);
|
|
@@ -1109,6 +1110,8 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
|
|
|
|
|
|
|
|
skb_queue_head_init(&pending);
|
|
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 */
|
|
/* Send all buffered frames to the station */
|
|
|
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
|
|
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
|
|
|
int count = skb_queue_len(&pending), tmp;
|
|
int count = skb_queue_len(&pending), tmp;
|
|
@@ -1128,6 +1131,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
ieee80211_add_pending_skbs_fn(local, &pending, clear_sta_ps_flags, sta);
|
|
ieee80211_add_pending_skbs_fn(local, &pending, clear_sta_ps_flags, sta);
|
|
|
|
|
+ spin_unlock(&sta->ps_lock);
|
|
|
|
|
|
|
|
/* This station just woke up and isn't aware of our SMPS state */
|
|
/* This station just woke up and isn't aware of our SMPS state */
|
|
|
if (!ieee80211_smps_is_restrictive(sta->known_smps_mode,
|
|
if (!ieee80211_smps_is_restrictive(sta->known_smps_mode,
|