diff options
author | Patrick McHardy <kaber@trash.net> | 2010-04-20 16:02:01 +0200 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2010-04-20 16:02:01 +0200 |
commit | 62910554656cdcd6b6f84a5154c4155aae4ca231 (patch) | |
tree | dcf14004f6fd2ef7154362ff948bfeba0f3ea92d /net/mac80211/tx.c | |
parent | 22265a5c3c103cf8c50be62e6c90d045eb649e6d (diff) | |
parent | ab9304717f7624c41927f442e6b6d418b2d8b3e4 (diff) |
Merge branch 'master' of /repos/git/net-next-2.6
Conflicts:
Documentation/feature-removal-schedule.txt
net/ipv6/netfilter/ip6t_REJECT.c
net/netfilter/xt_limit.c
Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r-- | net/mac80211/tx.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index cbe53ed4fb0b..2cb77267f733 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -513,6 +513,8 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) else if (tx->sta && (key = rcu_dereference(tx->sta->key))) tx->key = key; else if (ieee80211_is_mgmt(hdr->frame_control) && + is_multicast_ether_addr(hdr->addr1) && + ieee80211_is_robust_mgmt_frame(hdr) && (key = rcu_dereference(tx->sdata->default_mgmt_key))) tx->key = key; else if ((key = rcu_dereference(tx->sdata->default_key))) @@ -1142,13 +1144,12 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) && (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)) { - unsigned long flags; struct tid_ampdu_tx *tid_tx; qc = ieee80211_get_qos_ctl(hdr); tid = *qc & IEEE80211_QOS_CTL_TID_MASK; - spin_lock_irqsave(&tx->sta->lock, flags); + spin_lock(&tx->sta->lock); /* * XXX: This spinlock could be fairly expensive, but see the * comment in agg-tx.c:ieee80211_agg_tx_operational(). @@ -1173,7 +1174,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; __skb_queue_tail(&tid_tx->pending, skb); } - spin_unlock_irqrestore(&tx->sta->lock, flags); + spin_unlock(&tx->sta->lock); if (unlikely(queued)) return TX_QUEUED; @@ -1991,6 +1992,7 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local, void ieee80211_tx_pending(unsigned long data) { struct ieee80211_local *local = (struct ieee80211_local *)data; + struct ieee80211_sub_if_data *sdata; unsigned long flags; int i; bool txok; @@ -2010,14 +2012,12 @@ void ieee80211_tx_pending(unsigned long data) while (!skb_queue_empty(&local->pending[i])) { struct sk_buff *skb = __skb_dequeue(&local->pending[i]); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ieee80211_sub_if_data *sdata; if (WARN_ON(!info->control.vif)) { kfree_skb(skb); continue; } - sdata = vif_to_sdata(info->control.vif); spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); @@ -2029,6 +2029,11 @@ void ieee80211_tx_pending(unsigned long data) if (!txok) break; } + + if (skb_queue_empty(&local->pending[i])) + list_for_each_entry_rcu(sdata, &local->interfaces, list) + netif_tx_wake_queue( + netdev_get_tx_queue(sdata->dev, i)); } spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); |