mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-04 08:17:46 +00:00
ath9k_htc: Fix bug in aggregation initiation
Accessing the sta pointer in TX completion without approprate RCU protection is wrong. Fix this. Also, RCU protection is needed when the station's aggregation state is updated. Handle this properly. Signed-off-by: Sujith <Sujith.Manoharan@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
0995d11011
commit
ef98c3cd9b
2 changed files with 29 additions and 20 deletions
|
@ -412,32 +412,31 @@ static int ath9k_htc_aggr_oper(struct ath9k_htc_priv *priv,
|
|||
if (tid > ATH9K_HTC_MAX_TID)
|
||||
return -EINVAL;
|
||||
|
||||
rcu_read_lock();
|
||||
sta = ieee80211_find_sta(vif, sta_addr);
|
||||
if (sta) {
|
||||
ista = (struct ath9k_htc_sta *) sta->drv_priv;
|
||||
} else {
|
||||
rcu_read_unlock();
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!ista) {
|
||||
rcu_read_unlock();
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memset(&aggr, 0, sizeof(struct ath9k_htc_target_aggr));
|
||||
|
||||
aggr.sta_index = ista->index;
|
||||
rcu_read_unlock();
|
||||
aggr.tidno = tid;
|
||||
aggr.aggr_enable = oper;
|
||||
rcu_read_lock();
|
||||
|
||||
/* Check if we are able to retrieve the station */
|
||||
sta = ieee80211_find_sta(vif, sta_addr);
|
||||
if (!sta) {
|
||||
rcu_read_unlock();
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ista = (struct ath9k_htc_sta *) sta->drv_priv;
|
||||
|
||||
if (oper)
|
||||
ista->tid_state[tid] = AGGR_START;
|
||||
else
|
||||
ista->tid_state[tid] = AGGR_STOP;
|
||||
|
||||
aggr.sta_index = ista->index;
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
aggr.tidno = tid;
|
||||
aggr.aggr_enable = oper;
|
||||
|
||||
WMI_CMD_BUF(WMI_TX_AGGR_ENABLE_CMDID, &aggr);
|
||||
if (ret)
|
||||
ath_print(common, ATH_DBG_CONFIG,
|
||||
|
|
|
@ -188,10 +188,20 @@ void ath9k_tx_tasklet(unsigned long data)
|
|||
hdr = (struct ieee80211_hdr *) skb->data;
|
||||
fc = hdr->frame_control;
|
||||
tx_info = IEEE80211_SKB_CB(skb);
|
||||
sta = tx_info->control.sta;
|
||||
|
||||
memset(&tx_info->status, 0, sizeof(tx_info->status));
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
sta = ieee80211_find_sta(priv->vif, hdr->addr1);
|
||||
if (!sta) {
|
||||
rcu_read_unlock();
|
||||
ieee80211_tx_status(priv->hw, skb);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check if we need to start aggregation */
|
||||
|
||||
if (sta && conf_is_ht(&priv->hw->conf) &&
|
||||
(priv->op_flags & OP_TXAGGR)
|
||||
&& !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
|
||||
|
@ -213,7 +223,7 @@ void ath9k_tx_tasklet(unsigned long data)
|
|||
|
||||
rcu_read_unlock();
|
||||
|
||||
memset(&tx_info->status, 0, sizeof(tx_info->status));
|
||||
/* Send status to mac80211 */
|
||||
ieee80211_tx_status(priv->hw, skb);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue