/*
* Initialize information from queue
*/
- txdesc->queue = entry->queue->qid;
+ txdesc->qid = entry->queue->qid;
txdesc->cw_min = entry->queue->cw_min;
txdesc->cw_max = entry->queue->cw_max;
txdesc->aifs = entry->queue->aifs;
struct txentry_desc *txdesc)
{
struct data_queue *queue = entry->queue;
- struct rt2x00_dev *rt2x00dev = queue->rt2x00dev;
- rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, entry->skb, txdesc);
+ queue->rt2x00dev->ops->lib->write_tx_desc(entry, txdesc);
/*
* All processing on the frame has been completed, this means
* it is now ready to be dumped to userspace through debugfs.
*/
- rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TX, entry->skb);
+ rt2x00debug_dump_frame(queue->rt2x00dev, DUMP_FRAME_TX, entry->skb);
}
static void rt2x00queue_kick_tx_queue(struct queue_entry *entry,
*/
if (rt2x00queue_threshold(queue) ||
!test_bit(ENTRY_TXD_BURST, &txdesc->flags))
- rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, queue->qid);
+ rt2x00dev->ops->lib->kick_tx_queue(queue);
}
int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
intf->beacon->skb = NULL;
if (!enable_beacon) {
- rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, QID_BEACON);
+ rt2x00dev->ops->lib->kill_tx_queue(intf->beacon->queue);
mutex_unlock(&intf->beacon_skb_mutex);
return 0;
}
return 0;
}
+void rt2x00queue_for_each_entry(struct data_queue *queue,
+ enum queue_index start,
+ enum queue_index end,
+ void (*fn)(struct queue_entry *entry))
+{
+ unsigned long irqflags;
+ unsigned int index_start;
+ unsigned int index_end;
+ unsigned int i;
+
+ if (unlikely(start >= Q_INDEX_MAX || end >= Q_INDEX_MAX)) {
+ ERROR(queue->rt2x00dev,
+ "Entry requested from invalid index range (%d - %d)\n",
+ start, end);
+ return;
+ }
+
+ /*
+ * Only protect the range we are going to loop over,
+ * if during our loop a extra entry is set to pending
+ * it should not be kicked during this run, since it
+ * is part of another TX operation.
+ */
+ spin_lock_irqsave(&queue->lock, irqflags);
+ index_start = queue->index[start];
+ index_end = queue->index[end];
+ spin_unlock_irqrestore(&queue->lock, irqflags);
+
+ /*
+ * Start from the TX done pointer, this guarentees that we will
+ * send out all frames in the correct order.
+ */
+ if (index_start < index_end) {
+ for (i = index_start; i < index_end; i++)
+ fn(&queue->entries[i]);
+ } else {
+ for (i = index_start; i < queue->limit; i++)
+ fn(&queue->entries[i]);
+
+ for (i = 0; i < index_end; i++)
+ fn(&queue->entries[i]);
+ }
+}
+EXPORT_SYMBOL_GPL(rt2x00queue_for_each_entry);
+
struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev,
const enum data_queue_qid queue)
{
if (queue->index[index] >= queue->limit)
queue->index[index] = 0;
+ queue->last_action[index] = jiffies;
+
if (index == Q_INDEX) {
queue->length++;
- queue->last_index = jiffies;
} else if (index == Q_INDEX_DONE) {
queue->length--;
queue->count++;
- queue->last_index_done = jiffies;
}
spin_unlock_irqrestore(&queue->lock, irqflags);
static void rt2x00queue_reset(struct data_queue *queue)
{
unsigned long irqflags;
+ unsigned int i;
spin_lock_irqsave(&queue->lock, irqflags);
queue->count = 0;
queue->length = 0;
- queue->last_index = jiffies;
- queue->last_index_done = jiffies;
- memset(queue->index, 0, sizeof(queue->index));
+
+ for (i = 0; i < Q_INDEX_MAX; i++) {
+ queue->index[i] = 0;
+ queue->last_action[i] = jiffies;
+ }
spin_unlock_irqrestore(&queue->lock, irqflags);
}
struct data_queue *queue;
txall_queue_for_each(rt2x00dev, queue)
- rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, queue->qid);
+ rt2x00dev->ops->lib->kill_tx_queue(queue);
}
void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev)