diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2008-07-24 19:46:44 +0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-08-01 23:31:33 +0400 |
commit | f8e79ddd31c3615ddca26b9a469c44a7adbd4e13 (patch) | |
tree | befabd77386f496a3a5049bace1d335fcd8f8148 /net/mac80211/tx.c | |
parent | dc1968e7b7862bcd2d358c1be6119c011992bdd2 (diff) | |
download | linux-f8e79ddd31c3615ddca26b9a469c44a7adbd4e13.tar.xz |
mac80211: fix fragmentation kludge
This patch make mac80211 transmit correctly fragmented packet after
queue was stopped
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r-- | net/mac80211/tx.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 69019e943873..771ec68b848d 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1060,13 +1060,14 @@ static int ieee80211_tx_prepare(struct ieee80211_tx_data *tx, static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb, struct ieee80211_tx_data *tx) { - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_tx_info *info; int ret, i; - if (netif_subqueue_stopped(local->mdev, skb)) - return IEEE80211_TX_AGAIN; - if (skb) { + if (netif_subqueue_stopped(local->mdev, skb)) + return IEEE80211_TX_AGAIN; + info = IEEE80211_SKB_CB(skb); + ieee80211_dump_frame(wiphy_name(local->hw.wiphy), "TX to low-level driver", skb); ret = local->ops->tx(local_to_hw(local), skb); @@ -1215,6 +1216,7 @@ retry: if (ret == IEEE80211_TX_FRAG_AGAIN) skb = NULL; + set_bit(queue, local->queues_pending); smp_mb(); /* @@ -1708,14 +1710,19 @@ void ieee80211_tx_pending(unsigned long data) netif_tx_lock_bh(dev); for (i = 0; i < ieee80211_num_regular_queues(&local->hw); i++) { /* Check that this queue is ok */ - if (__netif_subqueue_stopped(local->mdev, i)) + if (__netif_subqueue_stopped(local->mdev, i) && + !test_bit(i, local->queues_pending_run)) continue; if (!test_bit(i, local->queues_pending)) { + clear_bit(i, local->queues_pending_run); ieee80211_wake_queue(&local->hw, i); continue; } + clear_bit(i, local->queues_pending_run); + netif_start_subqueue(local->mdev, i); + store = &local->pending_packet[i]; tx.extra_frag = store->extra_frag; tx.num_extra_frag = store->num_extra_frag; |