unsigned long state;
DECLARE_MAC_BUF(mac);
- spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
+ spin_lock_bh(&sta->lock);
state = sta->ampdu_mlme.tid_state_tx[tid];
- spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
+ spin_unlock_bh(&sta->lock);
if (state == HT_AGG_STATE_IDLE &&
rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) {
*/
if (params->station_flags & STATION_FLAG_CHANGED) {
+ spin_lock_bh(&sta->lock);
sta->flags &= ~WLAN_STA_AUTHORIZED;
if (params->station_flags & STATION_FLAG_AUTHORIZED)
sta->flags |= WLAN_STA_AUTHORIZED;
sta->flags &= ~WLAN_STA_WME;
if (params->station_flags & STATION_FLAG_WME)
sta->flags |= WLAN_STA_WME;
+ spin_unlock_bh(&sta->lock);
}
/*
{
char buf[100];
struct sta_info *sta = file->private_data;
+ u32 staflags = get_sta_flags(sta);
int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s",
- sta->flags & WLAN_STA_AUTH ? "AUTH\n" : "",
- sta->flags & WLAN_STA_ASSOC ? "ASSOC\n" : "",
- sta->flags & WLAN_STA_PS ? "PS\n" : "",
- sta->flags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "",
- sta->flags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "",
- sta->flags & WLAN_STA_WME ? "WME\n" : "",
- sta->flags & WLAN_STA_WDS ? "WDS\n" : "");
+ staflags & WLAN_STA_AUTH ? "AUTH\n" : "",
+ staflags & WLAN_STA_ASSOC ? "ASSOC\n" : "",
+ staflags & WLAN_STA_PS ? "PS\n" : "",
+ staflags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "",
+ staflags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "",
+ staflags & WLAN_STA_WME ? "WME\n" : "",
+ staflags & WLAN_STA_WDS ? "WDS\n" : "");
return simple_read_from_buffer(userbuf, count, ppos, buf, res);
}
STA_OPS(flags);
* some hardware cannot handle TKIP with QoS, so
* we indicate whether QoS could be in use.
*/
- if (sta->flags & WLAN_STA_WME)
+ if (test_sta_flags(sta, WLAN_STA_WME))
key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA;
/*
/* same here, the AP could be using QoS */
ap = sta_info_get(key->local, key->sdata->u.sta.bssid);
if (ap) {
- if (ap->flags & WLAN_STA_WME)
+ if (test_sta_flags(ap, WLAN_STA_WME))
key->conf.flags |=
IEEE80211_KEY_FLAG_WMM_STA;
}
goto err_del_interface;
}
+ /* no locking required since STA is not live yet */
sta->flags |= WLAN_STA_AUTHORIZED;
res = sta_info_insert(sta);
return -ENOENT;
}
- spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
+ spin_lock_bh(&sta->lock);
/* we have tried too many times, receiver does not want A-MPDU */
if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) {
spin_unlock_bh(&local->mdev->queue_lock);
ret = -EBUSY;
start_ba_exit:
- spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
+ spin_unlock_bh(&sta->lock);
rcu_read_unlock();
return ret;
}
/* check if the TID is in aggregation */
state = &sta->ampdu_mlme.tid_state_tx[tid];
- spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
+ spin_lock_bh(&sta->lock);
if (*state != HT_AGG_STATE_OPERATIONAL) {
ret = -ENOENT;
}
stop_BA_exit:
- spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
+ spin_unlock_bh(&sta->lock);
rcu_read_unlock();
return ret;
}
}
state = &sta->ampdu_mlme.tid_state_tx[tid];
- spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
+ spin_lock_bh(&sta->lock);
if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
printk(KERN_DEBUG "addBA was not requested yet, state is %d\n",
*state);
- spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
+ spin_unlock_bh(&sta->lock);
rcu_read_unlock();
return;
}
printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid);
ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
}
- spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
+ spin_unlock_bh(&sta->lock);
rcu_read_unlock();
}
EXPORT_SYMBOL(ieee80211_start_tx_ba_cb);
}
state = &sta->ampdu_mlme.tid_state_tx[tid];
- spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
+ spin_lock_bh(&sta->lock);
if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) {
printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n");
- spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
+ spin_unlock_bh(&sta->lock);
rcu_read_unlock();
return;
}
sta->ampdu_mlme.addba_req_num[tid] = 0;
kfree(sta->ampdu_mlme.tid_tx[tid]);
sta->ampdu_mlme.tid_tx[tid] = NULL;
- spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
+ spin_unlock_bh(&sta->lock);
rcu_read_unlock();
}
* packet. If the STA went to power save mode, this will happen
* happen when it wakes up for the next time.
*/
- sta->flags |= WLAN_STA_CLEAR_PS_FILT;
+ set_sta_flags(sta, WLAN_STA_CLEAR_PS_FILT);
/*
* This code races in the following way:
* can be unknown, for example with different interrupt status
* bits.
*/
- if (sta->flags & WLAN_STA_PS &&
+ if (test_sta_flags(sta, WLAN_STA_PS) &&
skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) {
ieee80211_remove_tx_extra(local, sta->key, skb,
&status->control);
return;
}
- if (!(sta->flags & WLAN_STA_PS) &&
+ if (!test_sta_flags(sta, WLAN_STA_PS) &&
!(status->control.flags & IEEE80211_TXCTL_REQUEUE)) {
/* Software retry the packet once */
status->control.flags |= IEEE80211_TXCTL_REQUEUE;
"queue_len=%d PS=%d @%lu\n",
wiphy_name(local->hw.wiphy),
skb_queue_len(&sta->tx_filtered),
- !!(sta->flags & WLAN_STA_PS), jiffies);
+ !!test_sta_flags(sta, WLAN_STA_PS), jiffies);
dev_kfree_skb(skb);
}
struct sta_info *sta;
sta = sta_info_get(local, hdr->addr1);
if (sta) {
- if (sta->flags & WLAN_STA_PS) {
+ if (test_sta_flags(sta, WLAN_STA_PS)) {
/*
* The STA is in power save mode, so assume
* that this TX packet failed because of that.
*
* @sta: mes peer link to restart
*
- * Locking: this function must be called holding sta->plink_lock
+ * Locking: this function must be called holding sta->lock
*/
static inline void mesh_plink_fsm_restart(struct sta_info *sta)
{
if (!sta)
return NULL;
- sta->flags |= WLAN_STA_AUTHORIZED;
+ sta->flags = WLAN_STA_AUTHORIZED;
sta->supp_rates[local->hw.conf.channel->band] = rates;
return sta;
*
* All mesh paths with this peer as next hop will be flushed
*
- * Locking: the caller must hold sta->plink_lock
+ * Locking: the caller must hold sta->lock
*/
static void __mesh_plink_deactivate(struct sta_info *sta)
{
*/
void mesh_plink_deactivate(struct sta_info *sta)
{
- spin_lock_bh(&sta->plink_lock);
+ spin_lock_bh(&sta->lock);
__mesh_plink_deactivate(sta);
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
}
static int mesh_plink_frame_tx(struct net_device *dev,
*/
sta = (struct sta_info *) data;
- spin_lock_bh(&sta->plink_lock);
+ spin_lock_bh(&sta->lock);
if (sta->ignore_plink_timer) {
sta->ignore_plink_timer = false;
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
return;
}
mpl_dbg("Mesh plink timer for %s fired on state %d\n",
rand % sta->plink_timeout;
++sta->plink_retries;
mod_plink_timer(sta, sta->plink_timeout);
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid,
0, 0);
break;
reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT);
sta->plink_state = PLINK_HOLDING;
mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, plid,
reason);
break;
/* holding timer */
del_timer(&sta->plink_timer);
mesh_plink_fsm_restart(sta);
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
break;
default:
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
break;
}
}
DECLARE_MAC_BUF(mac);
#endif
- spin_lock_bh(&sta->plink_lock);
+ spin_lock_bh(&sta->lock);
get_random_bytes(&llid, 2);
sta->llid = llid;
if (sta->plink_state != PLINK_LISTEN) {
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
return -EBUSY;
}
sta->plink_state = PLINK_OPN_SNT;
mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata));
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
mpl_dbg("Mesh plink: starting establishment with %s\n",
print_mac(mac, sta->addr));
DECLARE_MAC_BUF(mac);
#endif
- spin_lock_bh(&sta->plink_lock);
+ spin_lock_bh(&sta->lock);
__mesh_plink_deactivate(sta);
sta->plink_state = PLINK_BLOCKED;
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
}
int mesh_plink_close(struct sta_info *sta)
mpl_dbg("Mesh plink: closing link with %s\n",
print_mac(mac, sta->addr));
- spin_lock_bh(&sta->plink_lock);
+ spin_lock_bh(&sta->lock);
sta->reason = cpu_to_le16(MESH_LINK_CANCELLED);
reason = sta->reason;
if (sta->plink_state == PLINK_LISTEN ||
sta->plink_state == PLINK_BLOCKED) {
mesh_plink_fsm_restart(sta);
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
return 0;
} else if (sta->plink_state == PLINK_ESTAB) {
__mesh_plink_deactivate(sta);
sta->plink_state = PLINK_HOLDING;
llid = sta->llid;
plid = sta->plid;
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
mesh_plink_frame_tx(sta->sdata->dev, PLINK_CLOSE, sta->addr, llid,
plid, reason);
return 0;
/* avoid warning */
break;
}
- spin_lock_bh(&sta->plink_lock);
+ spin_lock_bh(&sta->lock);
} else if (!sta) {
/* ftype == PLINK_OPEN */
u64 rates;
return;
}
event = OPN_ACPT;
- spin_lock_bh(&sta->plink_lock);
+ spin_lock_bh(&sta->lock);
} else {
- spin_lock_bh(&sta->plink_lock);
+ spin_lock_bh(&sta->lock);
switch (ftype) {
case PLINK_OPEN:
if (!mesh_plink_free_count(sdata) ||
break;
default:
mpl_dbg("Mesh plink: unknown frame subtype\n");
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
rcu_read_unlock();
return;
}
switch (event) {
case CLS_ACPT:
mesh_plink_fsm_restart(sta);
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
break;
case OPN_ACPT:
sta->plink_state = PLINK_OPN_RCVD;
get_random_bytes(&llid, 2);
sta->llid = llid;
mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata));
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid,
0, 0);
mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr,
llid, plid, 0);
break;
default:
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
break;
}
break;
sta->ignore_plink_timer = true;
llid = sta->llid;
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
plid, reason);
break;
sta->plink_state = PLINK_OPN_RCVD;
sta->plid = plid;
llid = sta->llid;
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid,
plid, 0);
break;
dot11MeshConfirmTimeout(sdata)))
sta->ignore_plink_timer = true;
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
break;
default:
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
break;
}
break;
sta->ignore_plink_timer = true;
llid = sta->llid;
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
plid, reason);
break;
case OPN_ACPT:
llid = sta->llid;
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid,
plid, 0);
break;
del_timer(&sta->plink_timer);
sta->plink_state = PLINK_ESTAB;
mesh_plink_inc_estab_count(sdata);
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
mpl_dbg("Mesh plink with %s ESTABLISHED\n",
print_mac(mac, sta->addr));
break;
default:
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
break;
}
break;
sta->ignore_plink_timer = true;
llid = sta->llid;
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
plid, reason);
break;
del_timer(&sta->plink_timer);
sta->plink_state = PLINK_ESTAB;
mesh_plink_inc_estab_count(sdata);
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
mpl_dbg("Mesh plink with %s ESTABLISHED\n",
print_mac(mac, sta->addr));
mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid,
plid, 0);
break;
default:
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
break;
}
break;
sta->plink_state = PLINK_HOLDING;
llid = sta->llid;
mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
plid, reason);
break;
case OPN_ACPT:
llid = sta->llid;
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid,
plid, 0);
break;
default:
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
break;
}
break;
if (del_timer(&sta->plink_timer))
sta->ignore_plink_timer = 1;
mesh_plink_fsm_restart(sta);
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
break;
case OPN_ACPT:
case CNF_ACPT:
case CNF_RJCT:
llid = sta->llid;
reason = sta->reason;
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid,
plid, reason);
break;
default:
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
}
break;
default:
/* should not get here, PLINK_BLOCKED is dealt with at the
* beggining of the function
*/
- spin_unlock_bh(&sta->plink_lock);
+ spin_unlock_bh(&sta->lock);
break;
}
/* examine state machine */
- spin_lock_bh(&sta->ampdu_mlme.ampdu_rx);
+ spin_lock_bh(&sta->lock);
if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) {
#ifdef CONFIG_MAC80211_HT_DEBUG
tid_agg_rx->stored_mpdu_num = 0;
status = WLAN_STATUS_SUCCESS;
end:
- spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx);
+ spin_unlock_bh(&sta->lock);
end_no_lock:
ieee80211_send_addba_resp(sta->sdata->dev, sta->addr, tid,
state = &sta->ampdu_mlme.tid_state_tx[tid];
- spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
+ spin_lock_bh(&sta->lock);
if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
- spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
+ spin_unlock_bh(&sta->lock);
printk(KERN_DEBUG "state not HT_ADDBA_REQUESTED_MSK:"
"%d\n", *state);
goto addba_resp_exit;
if (mgmt->u.action.u.addba_resp.dialog_token !=
sta->ampdu_mlme.tid_tx[tid]->dialog_token) {
- spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
+ spin_unlock_bh(&sta->lock);
#ifdef CONFIG_MAC80211_HT_DEBUG
printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
#endif /* CONFIG_MAC80211_HT_DEBUG */
ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
}
- spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
+ spin_unlock_bh(&sta->lock);
printk(KERN_DEBUG "recipient accepted agg: tid %d \n", tid);
} else {
printk(KERN_DEBUG "recipient rejected agg: tid %d \n", tid);
sta->ampdu_mlme.addba_req_num[tid]++;
/* this will allow the state check in stop_BA_session */
*state = HT_AGG_STATE_OPERATIONAL;
- spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
+ spin_unlock_bh(&sta->lock);
ieee80211_stop_tx_ba_session(hw, sta->addr, tid,
WLAN_BACK_INITIATOR);
}
}
/* check if TID is in operational state */
- spin_lock_bh(&sta->ampdu_mlme.ampdu_rx);
+ spin_lock_bh(&sta->lock);
if (sta->ampdu_mlme.tid_state_rx[tid]
!= HT_AGG_STATE_OPERATIONAL) {
- spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx);
+ spin_unlock_bh(&sta->lock);
rcu_read_unlock();
return;
}
sta->ampdu_mlme.tid_state_rx[tid] =
HT_AGG_STATE_REQ_STOP_BA_MSK |
(initiator << HT_AGG_STATE_INITIATOR_SHIFT);
- spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx);
+ spin_unlock_bh(&sta->lock);
/* stop HW Rx aggregation. ampdu_action existence
* already verified in session init so we add the BUG_ON */
ieee80211_sta_stop_rx_ba_session(dev, sta->addr, tid,
WLAN_BACK_INITIATOR, 0);
else { /* WLAN_BACK_RECIPIENT */
- spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
+ spin_lock_bh(&sta->lock);
sta->ampdu_mlme.tid_state_tx[tid] =
HT_AGG_STATE_OPERATIONAL;
- spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
+ spin_unlock_bh(&sta->lock);
ieee80211_stop_tx_ba_session(&local->hw, sta->addr, tid,
WLAN_BACK_RECIPIENT);
}
state = &sta->ampdu_mlme.tid_state_tx[tid];
/* check if the TID waits for addBA response */
- spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
+ spin_lock_bh(&sta->lock);
if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
- spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
+ spin_unlock_bh(&sta->lock);
*state = HT_AGG_STATE_IDLE;
printk(KERN_DEBUG "timer expired on tid %d but we are not "
"expecting addBA response there", tid);
/* go through the state check in stop_BA_session */
*state = HT_AGG_STATE_OPERATIONAL;
- spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
+ spin_unlock_bh(&sta->lock);
ieee80211_stop_tx_ba_session(hw, temp_sta->addr, tid,
WLAN_BACK_INITIATOR);
* to between the sta_info_alloc() and sta_info_insert() above.
*/
- sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP |
- WLAN_STA_AUTHORIZED;
+ set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP |
+ WLAN_STA_AUTHORIZED);
rates = 0;
basic_rates = 0;
rate_control_rate_init(sta, local);
if (elems.wmm_param) {
- sta->flags |= WLAN_STA_WME;
+ set_sta_flags(sta, WLAN_STA_WME);
rcu_read_unlock();
ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param,
elems.wmm_param_len);
if (!sta)
return NULL;
- sta->flags |= WLAN_STA_AUTHORIZED;
+ set_sta_flags(sta, WLAN_STA_AUTHORIZED);
sta->supp_rates[local->hw.conf.channel->band] =
sdata->u.sta.supp_rates_bits[local->hw.conf.channel->band];
((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL &&
(rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)) &&
rx->sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
- (!rx->sta || !(rx->sta->flags & WLAN_STA_ASSOC)))) {
+ (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) {
if ((!(rx->fc & IEEE80211_FCTL_FROMDS) &&
!(rx->fc & IEEE80211_FCTL_TODS) &&
(rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)
if (sdata->bss)
atomic_inc(&sdata->bss->num_sta_ps);
- sta->flags |= WLAN_STA_PS;
- sta->flags &= ~WLAN_STA_PSPOLL;
+ set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL);
#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
printk(KERN_DEBUG "%s: STA %s aid %d enters power save mode\n",
dev->name, print_mac(mac, sta->addr), sta->aid);
if (sdata->bss)
atomic_dec(&sdata->bss->num_sta_ps);
- sta->flags &= ~(WLAN_STA_PS | WLAN_STA_PSPOLL);
+ clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL);
if (!skb_queue_empty(&sta->ps_tx_buf))
sta_info_clear_tim_bit(sta);
if (!(rx->fc & IEEE80211_FCTL_MOREFRAGS)) {
/* Change STA power saving mode only in the end of a frame
* exchange sequence */
- if ((sta->flags & WLAN_STA_PS) && !(rx->fc & IEEE80211_FCTL_PM))
+ if (test_sta_flags(sta, WLAN_STA_PS) &&
+ !(rx->fc & IEEE80211_FCTL_PM))
rx->sent_ps_buffered += ap_sta_ps_end(dev, sta);
- else if (!(sta->flags & WLAN_STA_PS) &&
+ else if (!test_sta_flags(sta, WLAN_STA_PS) &&
(rx->fc & IEEE80211_FCTL_PM))
ap_sta_ps_start(dev, sta);
}
* Tell TX path to send one frame even though the STA may
* still remain is PS mode after this frame exchange.
*/
- rx->sta->flags |= WLAN_STA_PSPOLL;
+ set_sta_flags(rx->sta, WLAN_STA_PSPOLL);
#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
printk(KERN_DEBUG "STA %s aid %d: PS Poll (entries after %d)\n",
static int
ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx)
{
- if (unlikely(!rx->sta || !(rx->sta->flags & WLAN_STA_AUTHORIZED))) {
+ if (unlikely(!rx->sta ||
+ !test_sta_flags(rx->sta, WLAN_STA_AUTHORIZED))) {
#ifdef CONFIG_MAC80211_DEBUG
if (net_ratelimit())
printk(KERN_DEBUG "%s: dropped frame "
dev_kfree_skb_any(skb);
for (i = 0; i < STA_TID_NUM; i++) {
- spin_lock_bh(&sta->ampdu_mlme.ampdu_rx);
+ spin_lock_bh(&sta->lock);
if (sta->ampdu_mlme.tid_rx[i])
del_timer_sync(&sta->ampdu_mlme.tid_rx[i]->session_timer);
- spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx);
- spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
if (sta->ampdu_mlme.tid_tx[i])
del_timer_sync(&sta->ampdu_mlme.tid_tx[i]->addba_resp_timer);
- spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
+ spin_unlock_bh(&sta->lock);
}
__sta_info_free(local, sta);
if (!sta)
return NULL;
+ spin_lock_init(&sta->lock);
+
memcpy(sta->addr, addr, ETH_ALEN);
sta->local = local;
sta->sdata = sdata;
return NULL;
}
- spin_lock_init(&sta->ampdu_mlme.ampdu_rx);
- spin_lock_init(&sta->ampdu_mlme.ampdu_tx);
for (i = 0; i < STA_TID_NUM; i++) {
/* timer_to_tid must be initialized with identity mapping to
* enable session_timer's data differentiation. refer to
#ifdef CONFIG_MAC80211_MESH
sta->plink_state = PLINK_LISTEN;
- spin_lock_init(&sta->plink_lock);
init_timer(&sta->plink_timer);
#endif
list_del(&(*sta)->list);
- if ((*sta)->flags & WLAN_STA_PS) {
- (*sta)->flags &= ~WLAN_STA_PS;
+ if (test_and_clear_sta_flags(*sta, WLAN_STA_PS)) {
if (sdata->bss)
atomic_dec(&sdata->bss->num_sta_ps);
__sta_info_clear_tim_bit(sdata->bss, *sta);
*
* @tid_state_rx: TID's state in Rx session state machine.
* @tid_rx: aggregation info for Rx per TID
- * @ampdu_rx: for locking sections in aggregation Rx flow
* @tid_state_tx: TID's state in Tx session state machine.
* @tid_tx: aggregation info for Tx per TID
* @addba_req_num: number of times addBA request has been sent.
- * @ampdu_tx: for locking sectionsi in aggregation Tx flow
* @dialog_token_allocator: dialog token enumerator for each new session;
*/
struct sta_ampdu_mlme {
/* rx */
u8 tid_state_rx[STA_TID_NUM];
struct tid_ampdu_rx *tid_rx[STA_TID_NUM];
- spinlock_t ampdu_rx;
/* tx */
u8 tid_state_tx[STA_TID_NUM];
struct tid_ampdu_tx *tid_tx[STA_TID_NUM];
u8 addba_req_num[STA_TID_NUM];
- spinlock_t ampdu_tx;
u8 dialog_token_allocator;
};
* @rx_bytes: Number of bytes received from this STA
* @supp_rates: Bitmap of supported rates (per band)
* @ht_info: HT capabilities of this STA
+ * @lock: used for locking all fields that require locking, see comments
+ * in the header file.
*/
struct sta_info {
/* General information, mostly static */
struct ieee80211_key *key;
struct rate_control_ref *rate_ctrl;
void *rate_ctrl_priv;
+ spinlock_t lock;
struct ieee80211_ht_info ht_info;
u64 supp_rates[IEEE80211_NUM_BANDS];
u8 addr[ETH_ALEN];
*/
u8 pin_status;
- /* frequently updated information, needs locking? */
+ /* frequently updated information, locked with lock spinlock */
u32 flags;
/*
int channel_use_raw;
/*
- * Aggregation information, comes with own locking.
+ * Aggregation information, locked with lock.
*/
struct sta_ampdu_mlme ampdu_mlme;
u8 timer_to_tid[STA_TID_NUM]; /* identity mapping to ID timers */
enum plink_state plink_state;
u32 plink_timeout;
struct timer_list plink_timer;
- spinlock_t plink_lock; /* For peer_state reads / updates and other
- updates in the structure. Ensures robust
- transitions for the peerlink FSM */
#endif
#ifdef CONFIG_MAC80211_DEBUGFS
return PLINK_LISTEN;
}
+static inline void set_sta_flags(struct sta_info *sta, const u32 flags)
+{
+ spin_lock_bh(&sta->lock);
+ sta->flags |= flags;
+ spin_unlock_bh(&sta->lock);
+}
+
+static inline void clear_sta_flags(struct sta_info *sta, const u32 flags)
+{
+ spin_lock_bh(&sta->lock);
+ sta->flags &= ~flags;
+ spin_unlock_bh(&sta->lock);
+}
+
+static inline void set_and_clear_sta_flags(struct sta_info *sta,
+ const u32 set, const u32 clear)
+{
+ spin_lock_bh(&sta->lock);
+ sta->flags |= set;
+ sta->flags &= ~clear;
+ spin_unlock_bh(&sta->lock);
+}
+
+static inline u32 test_sta_flags(struct sta_info *sta, const u32 flags)
+{
+ u32 ret;
+
+ spin_lock_bh(&sta->lock);
+ ret = sta->flags & flags;
+ spin_unlock_bh(&sta->lock);
+
+ return ret;
+}
+
+static inline u32 test_and_clear_sta_flags(struct sta_info *sta,
+ const u32 flags)
+{
+ u32 ret;
+
+ spin_lock_bh(&sta->lock);
+ ret = sta->flags & flags;
+ sta->flags &= ~flags;
+ spin_unlock_bh(&sta->lock);
+
+ return ret;
+}
+
+static inline u32 get_sta_flags(struct sta_info *sta)
+{
+ u32 ret;
+
+ spin_lock_bh(&sta->lock);
+ ret = sta->flags;
+ spin_unlock_bh(&sta->lock);
+
+ return ret;
+}
+
/* Maximum number of concurrently registered stations */
#define MAX_STA_COUNT 2007
if (tx->flags & IEEE80211_TX_PS_BUFFERED)
return TX_CONTINUE;
- sta_flags = tx->sta ? tx->sta->flags : 0;
+ sta_flags = tx->sta ? get_sta_flags(tx->sta) : 0;
if (likely(tx->flags & IEEE80211_TX_UNICAST)) {
if (unlikely(!(sta_flags & WLAN_STA_ASSOC) &&
ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
{
struct sta_info *sta = tx->sta;
+ u32 staflags;
DECLARE_MAC_BUF(mac);
if (unlikely(!sta ||
(tx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP)))
return TX_CONTINUE;
- if (unlikely((sta->flags & WLAN_STA_PS) &&
- !(sta->flags & WLAN_STA_PSPOLL))) {
+ staflags = get_sta_flags(sta);
+
+ if (unlikely((staflags & WLAN_STA_PS) &&
+ !(staflags & WLAN_STA_PSPOLL))) {
struct ieee80211_tx_packet_data *pkt_data;
#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
printk(KERN_DEBUG "STA %s aid %d: PS buffer (entries "
return TX_QUEUED;
}
#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
- else if (unlikely(sta->flags & WLAN_STA_PS)) {
+ else if (unlikely(test_sta_flags(sta, WLAN_STA_PS))) {
printk(KERN_DEBUG "%s: STA %s in PS mode, but pspoll "
"set -> send frame\n", tx->dev->name,
print_mac(mac, sta->addr));
}
#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
- sta->flags &= ~WLAN_STA_PSPOLL;
+ clear_sta_flags(sta, WLAN_STA_PSPOLL);
return TX_CONTINUE;
}
if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) &&
(tx->rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) &&
tx->sdata->bss_conf.use_short_preamble &&
- (!tx->sta || (tx->sta->flags & WLAN_STA_SHORT_PREAMBLE))) {
+ (!tx->sta || test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE))) {
tx->control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE;
}
if (!tx->sta)
control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT;
- else if (tx->sta->flags & WLAN_STA_CLEAR_PS_FILT) {
+ else if (test_and_clear_sta_flags(tx->sta, WLAN_STA_CLEAR_PS_FILT))
control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT;
- tx->sta->flags &= ~WLAN_STA_CLEAR_PS_FILT;
- }
hdrlen = ieee80211_get_hdrlen(tx->fc);
if (skb->len > hdrlen + sizeof(rfc1042_header) + 2) {
rcu_read_lock();
sta = sta_info_get(local, hdr.addr1);
if (sta)
- sta_flags = sta->flags;
+ sta_flags = get_sta_flags(sta);
rcu_read_unlock();
}