aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/tx.c
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2008-07-24 11:46:44 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-08-01 15:31:33 -0400
commitf8e79ddd31c3615ddca26b9a469c44a7adbd4e13 (patch)
treebefabd77386f496a3a5049bace1d335fcd8f8148 /net/mac80211/tx.c
parentdc1968e7b7862bcd2d358c1be6119c011992bdd2 (diff)
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.c17
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,
1060static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb, 1060static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb,
1061 struct ieee80211_tx_data *tx) 1061 struct ieee80211_tx_data *tx)
1062{ 1062{
1063 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1063 struct ieee80211_tx_info *info;
1064 int ret, i; 1064 int ret, i;
1065 1065
1066 if (netif_subqueue_stopped(local->mdev, skb))
1067 return IEEE80211_TX_AGAIN;
1068
1069 if (skb) { 1066 if (skb) {
1067 if (netif_subqueue_stopped(local->mdev, skb))
1068 return IEEE80211_TX_AGAIN;
1069 info = IEEE80211_SKB_CB(skb);
1070
1070 ieee80211_dump_frame(wiphy_name(local->hw.wiphy), 1071 ieee80211_dump_frame(wiphy_name(local->hw.wiphy),
1071 "TX to low-level driver", skb); 1072 "TX to low-level driver", skb);
1072 ret = local->ops->tx(local_to_hw(local), skb); 1073 ret = local->ops->tx(local_to_hw(local), skb);
@@ -1215,6 +1216,7 @@ retry:
1215 1216
1216 if (ret == IEEE80211_TX_FRAG_AGAIN) 1217 if (ret == IEEE80211_TX_FRAG_AGAIN)
1217 skb = NULL; 1218 skb = NULL;
1219
1218 set_bit(queue, local->queues_pending); 1220 set_bit(queue, local->queues_pending);
1219 smp_mb(); 1221 smp_mb();
1220 /* 1222 /*
@@ -1708,14 +1710,19 @@ void ieee80211_tx_pending(unsigned long data)
1708 netif_tx_lock_bh(dev); 1710 netif_tx_lock_bh(dev);
1709 for (i = 0; i < ieee80211_num_regular_queues(&local->hw); i++) { 1711 for (i = 0; i < ieee80211_num_regular_queues(&local->hw); i++) {
1710 /* Check that this queue is ok */ 1712 /* Check that this queue is ok */
1711 if (__netif_subqueue_stopped(local->mdev, i)) 1713 if (__netif_subqueue_stopped(local->mdev, i) &&
1714 !test_bit(i, local->queues_pending_run))
1712 continue; 1715 continue;
1713 1716
1714 if (!test_bit(i, local->queues_pending)) { 1717 if (!test_bit(i, local->queues_pending)) {
1718 clear_bit(i, local->queues_pending_run);
1715 ieee80211_wake_queue(&local->hw, i); 1719 ieee80211_wake_queue(&local->hw, i);
1716 continue; 1720 continue;
1717 } 1721 }
1718 1722
1723 clear_bit(i, local->queues_pending_run);
1724 netif_start_subqueue(local->mdev, i);
1725
1719 store = &local->pending_packet[i]; 1726 store = &local->pending_packet[i];
1720 tx.extra_frag = store->extra_frag; 1727 tx.extra_frag = store->extra_frag;
1721 tx.num_extra_frag = store->num_extra_frag; 1728 tx.num_extra_frag = store->num_extra_frag;