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;
}
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;
}
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)
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);
void sta_info_stop(struct ieee80211_local *local)
{
- del_timer(&local->sta_cleanup);
+ del_timer_sync(&local->sta_cleanup);
sta_info_flush(local, NULL);
}
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);
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;
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]);