diff options
author | Ivo van Doorn <IvDoorn@gmail.com> | 2008-06-06 16:53:14 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-06-14 12:17:56 -0400 |
commit | b869767b6f5049f1d1ede2bb3e48832e0722ca5a (patch) | |
tree | a75e43aad931ffdaea889af7b2275f12a16f077a /drivers/net/wireless/rt2x00/rt2x00queue.c | |
parent | 6db3786aee36b32e5ed072ed67fad6d5341b0991 (diff) |
rt2x00: Don't kick TX queue after each frame
TX queues shouldn't be kicked after each frame that is put into the
queue. This could cause problems during RTS and CTS-to-self as well
as with fragmentation. In all those cases you want all frames to be
send out in a single burst. Off course we shouldn't let the queue fill
up entirely, thus we introduce a 10% threshold which, when reached,
will force the frames to be send out regardless of the frame.
In addition we should prevent queues to become full in such a way
that the tx() handler can fail. Instead of stopping the queue when
it is full, we should stop it when it is below the threshold.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00queue.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00queue.c | 28 |
1 files changed, 17 insertions, 11 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index f875b7ab09fe..493066519ef3 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -163,8 +163,8 @@ EXPORT_SYMBOL_GPL(rt2x00queue_create_tx_descriptor); | |||
163 | void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, | 163 | void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, |
164 | struct txentry_desc *txdesc) | 164 | struct txentry_desc *txdesc) |
165 | { | 165 | { |
166 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 166 | struct data_queue *queue = entry->queue; |
167 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | 167 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; |
168 | 168 | ||
169 | rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, entry->skb, txdesc); | 169 | rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, entry->skb, txdesc); |
170 | 170 | ||
@@ -175,16 +175,21 @@ void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, | |||
175 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TX, entry->skb); | 175 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TX, entry->skb); |
176 | 176 | ||
177 | /* | 177 | /* |
178 | * We are done writing the frame to the queue entry, | 178 | * Check if we need to kick the queue, there are however a few rules |
179 | * also kick the queue in case the correct flags are set, | 179 | * 1) Don't kick beacon queue |
180 | * note that this will automatically filter beacons and | 180 | * 2) Don't kick unless this is the last in frame in a burst. |
181 | * RTS/CTS frames since those frames don't have this flag | 181 | * When the burst flag is set, this frame is always followed |
182 | * set. | 182 | * by another frame which in some way are related to eachother. |
183 | * This is true for fragments, RTS or CTS-to-self frames. | ||
184 | * 3) Rule 2 can be broken when the available entries | ||
185 | * in the queue are less then a certain threshold. | ||
183 | */ | 186 | */ |
184 | if (rt2x00dev->ops->lib->kick_tx_queue && | 187 | if (entry->queue->qid == QID_BEACON) |
185 | !(skbdesc->flags & FRAME_DESC_DRIVER_GENERATED)) | 188 | return; |
186 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, | 189 | |
187 | entry->queue->qid); | 190 | if (rt2x00queue_threshold(queue) || |
191 | !test_bit(ENTRY_TXD_BURST, &txdesc->flags)) | ||
192 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, queue->qid); | ||
188 | } | 193 | } |
189 | EXPORT_SYMBOL_GPL(rt2x00queue_write_tx_descriptor); | 194 | EXPORT_SYMBOL_GPL(rt2x00queue_write_tx_descriptor); |
190 | 195 | ||
@@ -349,6 +354,7 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue, | |||
349 | rt2x00queue_reset(queue); | 354 | rt2x00queue_reset(queue); |
350 | 355 | ||
351 | queue->limit = qdesc->entry_num; | 356 | queue->limit = qdesc->entry_num; |
357 | queue->threshold = DIV_ROUND_UP(qdesc->entry_num, 10); | ||
352 | queue->data_size = qdesc->data_size; | 358 | queue->data_size = qdesc->data_size; |
353 | queue->desc_size = qdesc->desc_size; | 359 | queue->desc_size = qdesc->desc_size; |
354 | 360 | ||