diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00queue.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00queue.c | 71 |
1 files changed, 59 insertions, 12 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 480d33a3ce42..eede99939db9 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -312,7 +312,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | |||
312 | /* | 312 | /* |
313 | * Initialize information from queue | 313 | * Initialize information from queue |
314 | */ | 314 | */ |
315 | txdesc->queue = entry->queue->qid; | 315 | txdesc->qid = entry->queue->qid; |
316 | txdesc->cw_min = entry->queue->cw_min; | 316 | txdesc->cw_min = entry->queue->cw_min; |
317 | txdesc->cw_max = entry->queue->cw_max; | 317 | txdesc->cw_max = entry->queue->cw_max; |
318 | txdesc->aifs = entry->queue->aifs; | 318 | txdesc->aifs = entry->queue->aifs; |
@@ -449,15 +449,14 @@ static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, | |||
449 | struct txentry_desc *txdesc) | 449 | struct txentry_desc *txdesc) |
450 | { | 450 | { |
451 | struct data_queue *queue = entry->queue; | 451 | struct data_queue *queue = entry->queue; |
452 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; | ||
453 | 452 | ||
454 | rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, entry->skb, txdesc); | 453 | queue->rt2x00dev->ops->lib->write_tx_desc(entry, txdesc); |
455 | 454 | ||
456 | /* | 455 | /* |
457 | * All processing on the frame has been completed, this means | 456 | * All processing on the frame has been completed, this means |
458 | * it is now ready to be dumped to userspace through debugfs. | 457 | * it is now ready to be dumped to userspace through debugfs. |
459 | */ | 458 | */ |
460 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TX, entry->skb); | 459 | rt2x00debug_dump_frame(queue->rt2x00dev, DUMP_FRAME_TX, entry->skb); |
461 | } | 460 | } |
462 | 461 | ||
463 | static void rt2x00queue_kick_tx_queue(struct queue_entry *entry, | 462 | static void rt2x00queue_kick_tx_queue(struct queue_entry *entry, |
@@ -477,7 +476,7 @@ static void rt2x00queue_kick_tx_queue(struct queue_entry *entry, | |||
477 | */ | 476 | */ |
478 | if (rt2x00queue_threshold(queue) || | 477 | if (rt2x00queue_threshold(queue) || |
479 | !test_bit(ENTRY_TXD_BURST, &txdesc->flags)) | 478 | !test_bit(ENTRY_TXD_BURST, &txdesc->flags)) |
480 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, queue->qid); | 479 | rt2x00dev->ops->lib->kick_tx_queue(queue); |
481 | } | 480 | } |
482 | 481 | ||
483 | int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, | 482 | int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, |
@@ -591,7 +590,7 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, | |||
591 | intf->beacon->skb = NULL; | 590 | intf->beacon->skb = NULL; |
592 | 591 | ||
593 | if (!enable_beacon) { | 592 | if (!enable_beacon) { |
594 | rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, QID_BEACON); | 593 | rt2x00dev->ops->lib->kill_tx_queue(intf->beacon->queue); |
595 | mutex_unlock(&intf->beacon_skb_mutex); | 594 | mutex_unlock(&intf->beacon_skb_mutex); |
596 | return 0; | 595 | return 0; |
597 | } | 596 | } |
@@ -626,6 +625,51 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, | |||
626 | return 0; | 625 | return 0; |
627 | } | 626 | } |
628 | 627 | ||
628 | void rt2x00queue_for_each_entry(struct data_queue *queue, | ||
629 | enum queue_index start, | ||
630 | enum queue_index end, | ||
631 | void (*fn)(struct queue_entry *entry)) | ||
632 | { | ||
633 | unsigned long irqflags; | ||
634 | unsigned int index_start; | ||
635 | unsigned int index_end; | ||
636 | unsigned int i; | ||
637 | |||
638 | if (unlikely(start >= Q_INDEX_MAX || end >= Q_INDEX_MAX)) { | ||
639 | ERROR(queue->rt2x00dev, | ||
640 | "Entry requested from invalid index range (%d - %d)\n", | ||
641 | start, end); | ||
642 | return; | ||
643 | } | ||
644 | |||
645 | /* | ||
646 | * Only protect the range we are going to loop over, | ||
647 | * if during our loop a extra entry is set to pending | ||
648 | * it should not be kicked during this run, since it | ||
649 | * is part of another TX operation. | ||
650 | */ | ||
651 | spin_lock_irqsave(&queue->lock, irqflags); | ||
652 | index_start = queue->index[start]; | ||
653 | index_end = queue->index[end]; | ||
654 | spin_unlock_irqrestore(&queue->lock, irqflags); | ||
655 | |||
656 | /* | ||
657 | * Start from the TX done pointer, this guarentees that we will | ||
658 | * send out all frames in the correct order. | ||
659 | */ | ||
660 | if (index_start < index_end) { | ||
661 | for (i = index_start; i < index_end; i++) | ||
662 | fn(&queue->entries[i]); | ||
663 | } else { | ||
664 | for (i = index_start; i < queue->limit; i++) | ||
665 | fn(&queue->entries[i]); | ||
666 | |||
667 | for (i = 0; i < index_end; i++) | ||
668 | fn(&queue->entries[i]); | ||
669 | } | ||
670 | } | ||
671 | EXPORT_SYMBOL_GPL(rt2x00queue_for_each_entry); | ||
672 | |||
629 | struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, | 673 | struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, |
630 | const enum data_queue_qid queue) | 674 | const enum data_queue_qid queue) |
631 | { | 675 | { |
@@ -687,13 +731,13 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index) | |||
687 | if (queue->index[index] >= queue->limit) | 731 | if (queue->index[index] >= queue->limit) |
688 | queue->index[index] = 0; | 732 | queue->index[index] = 0; |
689 | 733 | ||
734 | queue->last_action[index] = jiffies; | ||
735 | |||
690 | if (index == Q_INDEX) { | 736 | if (index == Q_INDEX) { |
691 | queue->length++; | 737 | queue->length++; |
692 | queue->last_index = jiffies; | ||
693 | } else if (index == Q_INDEX_DONE) { | 738 | } else if (index == Q_INDEX_DONE) { |
694 | queue->length--; | 739 | queue->length--; |
695 | queue->count++; | 740 | queue->count++; |
696 | queue->last_index_done = jiffies; | ||
697 | } | 741 | } |
698 | 742 | ||
699 | spin_unlock_irqrestore(&queue->lock, irqflags); | 743 | spin_unlock_irqrestore(&queue->lock, irqflags); |
@@ -702,14 +746,17 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index) | |||
702 | static void rt2x00queue_reset(struct data_queue *queue) | 746 | static void rt2x00queue_reset(struct data_queue *queue) |
703 | { | 747 | { |
704 | unsigned long irqflags; | 748 | unsigned long irqflags; |
749 | unsigned int i; | ||
705 | 750 | ||
706 | spin_lock_irqsave(&queue->lock, irqflags); | 751 | spin_lock_irqsave(&queue->lock, irqflags); |
707 | 752 | ||
708 | queue->count = 0; | 753 | queue->count = 0; |
709 | queue->length = 0; | 754 | queue->length = 0; |
710 | queue->last_index = jiffies; | 755 | |
711 | queue->last_index_done = jiffies; | 756 | for (i = 0; i < Q_INDEX_MAX; i++) { |
712 | memset(queue->index, 0, sizeof(queue->index)); | 757 | queue->index[i] = 0; |
758 | queue->last_action[i] = jiffies; | ||
759 | } | ||
713 | 760 | ||
714 | spin_unlock_irqrestore(&queue->lock, irqflags); | 761 | spin_unlock_irqrestore(&queue->lock, irqflags); |
715 | } | 762 | } |
@@ -719,7 +766,7 @@ void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev) | |||
719 | struct data_queue *queue; | 766 | struct data_queue *queue; |
720 | 767 | ||
721 | txall_queue_for_each(rt2x00dev, queue) | 768 | txall_queue_for_each(rt2x00dev, queue) |
722 | rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, queue->qid); | 769 | rt2x00dev->ops->lib->kill_tx_queue(queue); |
723 | } | 770 | } |
724 | 771 | ||
725 | void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev) | 772 | void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev) |