aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2008-11-08 09:25:33 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-11-21 11:08:16 -0500
commit798b7adb4ed3533ab1282f51d16892034cfd8aae (patch)
treeef328809a04c1072e9b1ce765d01f470283d4842 /drivers/net/wireless/rt2x00
parent0ed94eaaed618634f68197161203aac9f849471e (diff)
rt2x00: Cleanup TX/RX entry handling
Merge the callback functions init_txentry() and init_rxentry(). This makes life in rt2x00lib a lot simpler and we can cleanup several functions. rt2x00pci contained "fake" FIELD definitions for descriptor words. This is not flexible since it assumes the driver will always have the same field to indicate if a driver is available or not. This should be dependent on the driver, and we should add a callback function for this. 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')
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c51
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c45
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h6
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c7
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h12
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c13
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.h11
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c28
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c31
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.h5
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c47
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c3
13 files changed, 127 insertions, 135 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 42bd38ac7a1d..861577ece713 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -626,36 +626,47 @@ static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev)
626/* 626/*
627 * Initialization functions. 627 * Initialization functions.
628 */ 628 */
629static void rt2400pci_init_rxentry(struct rt2x00_dev *rt2x00dev, 629static bool rt2400pci_get_entry_state(struct queue_entry *entry)
630 struct queue_entry *entry)
631{ 630{
632 struct queue_entry_priv_pci *entry_priv = entry->priv_data; 631 struct queue_entry_priv_pci *entry_priv = entry->priv_data;
633 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
634 u32 word; 632 u32 word;
635 633
636 rt2x00_desc_read(entry_priv->desc, 2, &word); 634 if (entry->queue->qid == QID_RX) {
637 rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, entry->skb->len); 635 rt2x00_desc_read(entry_priv->desc, 0, &word);
638 rt2x00_desc_write(entry_priv->desc, 2, word);
639 636
640 rt2x00_desc_read(entry_priv->desc, 1, &word); 637 return rt2x00_get_field32(word, RXD_W0_OWNER_NIC);
641 rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); 638 } else {
642 rt2x00_desc_write(entry_priv->desc, 1, word); 639 rt2x00_desc_read(entry_priv->desc, 0, &word);
643 640
644 rt2x00_desc_read(entry_priv->desc, 0, &word); 641 return (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) ||
645 rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); 642 rt2x00_get_field32(word, TXD_W0_VALID));
646 rt2x00_desc_write(entry_priv->desc, 0, word); 643 }
647} 644}
648 645
649static void rt2400pci_init_txentry(struct rt2x00_dev *rt2x00dev, 646static void rt2400pci_clear_entry(struct queue_entry *entry)
650 struct queue_entry *entry)
651{ 647{
652 struct queue_entry_priv_pci *entry_priv = entry->priv_data; 648 struct queue_entry_priv_pci *entry_priv = entry->priv_data;
649 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
653 u32 word; 650 u32 word;
654 651
655 rt2x00_desc_read(entry_priv->desc, 0, &word); 652 if (entry->queue->qid == QID_RX) {
656 rt2x00_set_field32(&word, TXD_W0_VALID, 0); 653 rt2x00_desc_read(entry_priv->desc, 2, &word);
657 rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); 654 rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, entry->skb->len);
658 rt2x00_desc_write(entry_priv->desc, 0, word); 655 rt2x00_desc_write(entry_priv->desc, 2, word);
656
657 rt2x00_desc_read(entry_priv->desc, 1, &word);
658 rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
659 rt2x00_desc_write(entry_priv->desc, 1, word);
660
661 rt2x00_desc_read(entry_priv->desc, 0, &word);
662 rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
663 rt2x00_desc_write(entry_priv->desc, 0, word);
664 } else {
665 rt2x00_desc_read(entry_priv->desc, 0, &word);
666 rt2x00_set_field32(&word, TXD_W0_VALID, 0);
667 rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
668 rt2x00_desc_write(entry_priv->desc, 0, word);
669 }
659} 670}
660 671
661static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev) 672static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev)
@@ -1570,8 +1581,8 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
1570 .probe_hw = rt2400pci_probe_hw, 1581 .probe_hw = rt2400pci_probe_hw,
1571 .initialize = rt2x00pci_initialize, 1582 .initialize = rt2x00pci_initialize,
1572 .uninitialize = rt2x00pci_uninitialize, 1583 .uninitialize = rt2x00pci_uninitialize,
1573 .init_rxentry = rt2400pci_init_rxentry, 1584 .get_entry_state = rt2400pci_get_entry_state,
1574 .init_txentry = rt2400pci_init_txentry, 1585 .clear_entry = rt2400pci_clear_entry,
1575 .set_device_state = rt2400pci_set_device_state, 1586 .set_device_state = rt2400pci_set_device_state,
1576 .rfkill_poll = rt2400pci_rfkill_poll, 1587 .rfkill_poll = rt2400pci_rfkill_poll,
1577 .link_stats = rt2400pci_link_stats, 1588 .link_stats = rt2400pci_link_stats,
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 928452f30c25..e43ff9c79063 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -722,32 +722,43 @@ dynamic_cca_tune:
722/* 722/*
723 * Initialization functions. 723 * Initialization functions.
724 */ 724 */
725static void rt2500pci_init_rxentry(struct rt2x00_dev *rt2x00dev, 725static bool rt2500pci_get_entry_state(struct queue_entry *entry)
726 struct queue_entry *entry)
727{ 726{
728 struct queue_entry_priv_pci *entry_priv = entry->priv_data; 727 struct queue_entry_priv_pci *entry_priv = entry->priv_data;
729 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
730 u32 word; 728 u32 word;
731 729
732 rt2x00_desc_read(entry_priv->desc, 1, &word); 730 if (entry->queue->qid == QID_RX) {
733 rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); 731 rt2x00_desc_read(entry_priv->desc, 0, &word);
734 rt2x00_desc_write(entry_priv->desc, 1, word); 732
733 return rt2x00_get_field32(word, RXD_W0_OWNER_NIC);
734 } else {
735 rt2x00_desc_read(entry_priv->desc, 0, &word);
735 736
736 rt2x00_desc_read(entry_priv->desc, 0, &word); 737 return (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) ||
737 rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); 738 rt2x00_get_field32(word, TXD_W0_VALID));
738 rt2x00_desc_write(entry_priv->desc, 0, word); 739 }
739} 740}
740 741
741static void rt2500pci_init_txentry(struct rt2x00_dev *rt2x00dev, 742static void rt2500pci_clear_entry(struct queue_entry *entry)
742 struct queue_entry *entry)
743{ 743{
744 struct queue_entry_priv_pci *entry_priv = entry->priv_data; 744 struct queue_entry_priv_pci *entry_priv = entry->priv_data;
745 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
745 u32 word; 746 u32 word;
746 747
747 rt2x00_desc_read(entry_priv->desc, 0, &word); 748 if (entry->queue->qid == QID_RX) {
748 rt2x00_set_field32(&word, TXD_W0_VALID, 0); 749 rt2x00_desc_read(entry_priv->desc, 1, &word);
749 rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); 750 rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma);
750 rt2x00_desc_write(entry_priv->desc, 0, word); 751 rt2x00_desc_write(entry_priv->desc, 1, word);
752
753 rt2x00_desc_read(entry_priv->desc, 0, &word);
754 rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
755 rt2x00_desc_write(entry_priv->desc, 0, word);
756 } else {
757 rt2x00_desc_read(entry_priv->desc, 0, &word);
758 rt2x00_set_field32(&word, TXD_W0_VALID, 0);
759 rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
760 rt2x00_desc_write(entry_priv->desc, 0, word);
761 }
751} 762}
752 763
753static int rt2500pci_init_queues(struct rt2x00_dev *rt2x00dev) 764static int rt2500pci_init_queues(struct rt2x00_dev *rt2x00dev)
@@ -1871,8 +1882,8 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
1871 .probe_hw = rt2500pci_probe_hw, 1882 .probe_hw = rt2500pci_probe_hw,
1872 .initialize = rt2x00pci_initialize, 1883 .initialize = rt2x00pci_initialize,
1873 .uninitialize = rt2x00pci_uninitialize, 1884 .uninitialize = rt2x00pci_uninitialize,
1874 .init_rxentry = rt2500pci_init_rxentry, 1885 .get_entry_state = rt2500pci_get_entry_state,
1875 .init_txentry = rt2500pci_init_txentry, 1886 .clear_entry = rt2500pci_clear_entry,
1876 .set_device_state = rt2500pci_set_device_state, 1887 .set_device_state = rt2500pci_set_device_state,
1877 .rfkill_poll = rt2500pci_rfkill_poll, 1888 .rfkill_poll = rt2500pci_rfkill_poll,
1878 .link_stats = rt2500pci_link_stats, 1889 .link_stats = rt2500pci_link_stats,
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 639d5a2f84e2..3868e987438d 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1777,8 +1777,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
1777 .probe_hw = rt2500usb_probe_hw, 1777 .probe_hw = rt2500usb_probe_hw,
1778 .initialize = rt2x00usb_initialize, 1778 .initialize = rt2x00usb_initialize,
1779 .uninitialize = rt2x00usb_uninitialize, 1779 .uninitialize = rt2x00usb_uninitialize,
1780 .init_rxentry = rt2x00usb_init_rxentry, 1780 .clear_entry = rt2x00usb_clear_entry,
1781 .init_txentry = rt2x00usb_init_txentry,
1782 .set_device_state = rt2500usb_set_device_state, 1781 .set_device_state = rt2500usb_set_device_state,
1783 .link_stats = rt2500usb_link_stats, 1782 .link_stats = rt2500usb_link_stats,
1784 .reset_tuner = rt2500usb_reset_tuner, 1783 .reset_tuner = rt2500usb_reset_tuner,
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 8fa971ccfddd..4506f6cfc0c3 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -523,10 +523,8 @@ struct rt2x00lib_ops {
523 /* 523 /*
524 * queue initialization handlers 524 * queue initialization handlers
525 */ 525 */
526 void (*init_rxentry) (struct rt2x00_dev *rt2x00dev, 526 bool (*get_entry_state) (struct queue_entry *entry);
527 struct queue_entry *entry); 527 void (*clear_entry) (struct queue_entry *entry);
528 void (*init_txentry) (struct rt2x00_dev *rt2x00dev,
529 struct queue_entry *entry);
530 528
531 /* 529 /*
532 * Radio control handlers. 530 * Radio control handlers.
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index e8ca1cbfeb90..bb510a232d14 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -101,8 +101,7 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
101 /* 101 /*
102 * Initialize all data queues. 102 * Initialize all data queues.
103 */ 103 */
104 rt2x00queue_init_rx(rt2x00dev); 104 rt2x00queue_init_queues(rt2x00dev);
105 rt2x00queue_init_tx(rt2x00dev);
106 105
107 /* 106 /*
108 * Enable radio. 107 * Enable radio.
@@ -576,7 +575,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
576 entry->skb = NULL; 575 entry->skb = NULL;
577 entry->flags = 0; 576 entry->flags = 0;
578 577
579 rt2x00dev->ops->lib->init_txentry(rt2x00dev, entry); 578 rt2x00dev->ops->lib->clear_entry(entry);
580 579
581 clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); 580 clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
582 rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); 581 rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
@@ -708,7 +707,7 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
708 entry->skb = skb; 707 entry->skb = skb;
709 entry->flags = 0; 708 entry->flags = 0;
710 709
711 rt2x00dev->ops->lib->init_rxentry(rt2x00dev, entry); 710 rt2x00dev->ops->lib->clear_entry(entry);
712 711
713 rt2x00queue_index_inc(entry->queue, Q_INDEX); 712 rt2x00queue_index_inc(entry->queue, Q_INDEX);
714} 713}
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index 0c3a3559ba48..93997333d46d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -150,8 +150,16 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
150 */ 150 */
151void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index); 151void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index);
152 152
153void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev); 153/**
154void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev); 154 * rt2x00queue_init_queues - Initialize all data queues
155 * @rt2x00dev: Pointer to &struct rt2x00_dev.
156 *
157 * This function will loop through all available queues to clear all
158 * index numbers and set the queue entry to the correct initialization
159 * state.
160 */
161void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev);
162
155int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev); 163int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev);
156void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev); 164void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev);
157int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev); 165int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 62449da577e5..e33bd0f150c5 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -36,20 +36,17 @@
36 */ 36 */
37int rt2x00pci_write_tx_data(struct queue_entry *entry) 37int rt2x00pci_write_tx_data(struct queue_entry *entry)
38{ 38{
39 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
39 struct queue_entry_priv_pci *entry_priv = entry->priv_data; 40 struct queue_entry_priv_pci *entry_priv = entry->priv_data;
40 struct skb_frame_desc *skbdesc; 41 struct skb_frame_desc *skbdesc;
41 u32 word;
42
43 rt2x00_desc_read(entry_priv->desc, 0, &word);
44 42
45 /* 43 /*
46 * This should not happen, we already checked the entry 44 * This should not happen, we already checked the entry
47 * was ours. When the hardware disagrees there has been 45 * was ours. When the hardware disagrees there has been
48 * a queue corruption! 46 * a queue corruption!
49 */ 47 */
50 if (unlikely(rt2x00_get_field32(word, TXD_ENTRY_OWNER_NIC) || 48 if (unlikely(rt2x00dev->ops->lib->get_entry_state(entry))) {
51 rt2x00_get_field32(word, TXD_ENTRY_VALID))) { 49 ERROR(rt2x00dev,
52 ERROR(entry->queue->rt2x00dev,
53 "Corrupt queue %d, accessing entry which is not ours.\n" 50 "Corrupt queue %d, accessing entry which is not ours.\n"
54 "Please file bug report to %s.\n", 51 "Please file bug report to %s.\n",
55 entry->queue->qid, DRV_PROJECT); 52 entry->queue->qid, DRV_PROJECT);
@@ -76,14 +73,12 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
76 struct queue_entry *entry; 73 struct queue_entry *entry;
77 struct queue_entry_priv_pci *entry_priv; 74 struct queue_entry_priv_pci *entry_priv;
78 struct skb_frame_desc *skbdesc; 75 struct skb_frame_desc *skbdesc;
79 u32 word;
80 76
81 while (1) { 77 while (1) {
82 entry = rt2x00queue_get_entry(queue, Q_INDEX); 78 entry = rt2x00queue_get_entry(queue, Q_INDEX);
83 entry_priv = entry->priv_data; 79 entry_priv = entry->priv_data;
84 rt2x00_desc_read(entry_priv->desc, 0, &word);
85 80
86 if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC)) 81 if (rt2x00dev->ops->lib->get_entry_state(entry))
87 break; 82 break;
88 83
89 /* 84 /*
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h
index a83f45f784f2..96a2082a3532 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.h
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.h
@@ -44,17 +44,6 @@
44#define REGISTER_BUSY_DELAY 100 44#define REGISTER_BUSY_DELAY 100
45 45
46/* 46/*
47 * Descriptor availability flags.
48 * All PCI device descriptors have these 2 flags
49 * with the exact same definition.
50 * By storing them here we can use them inside rt2x00pci
51 * for some simple entry availability checking.
52 */
53#define TXD_ENTRY_OWNER_NIC FIELD32(0x00000001)
54#define TXD_ENTRY_VALID FIELD32(0x00000002)
55#define RXD_ENTRY_OWNER_NIC FIELD32(0x00000001)
56
57/*
58 * Register access. 47 * Register access.
59 */ 48 */
60static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev, 49static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev,
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index e9f4261054bc..7fc9c6eff98b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -589,40 +589,18 @@ static void rt2x00queue_reset(struct data_queue *queue)
589 spin_unlock_irqrestore(&queue->lock, irqflags); 589 spin_unlock_irqrestore(&queue->lock, irqflags);
590} 590}
591 591
592void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev) 592void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev)
593{
594 struct data_queue *queue = rt2x00dev->rx;
595 unsigned int i;
596
597 rt2x00queue_reset(queue);
598
599 if (!rt2x00dev->ops->lib->init_rxentry)
600 return;
601
602 for (i = 0; i < queue->limit; i++) {
603 queue->entries[i].flags = 0;
604
605 rt2x00dev->ops->lib->init_rxentry(rt2x00dev,
606 &queue->entries[i]);
607 }
608}
609
610void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev)
611{ 593{
612 struct data_queue *queue; 594 struct data_queue *queue;
613 unsigned int i; 595 unsigned int i;
614 596
615 txall_queue_for_each(rt2x00dev, queue) { 597 queue_for_each(rt2x00dev, queue) {
616 rt2x00queue_reset(queue); 598 rt2x00queue_reset(queue);
617 599
618 if (!rt2x00dev->ops->lib->init_txentry)
619 continue;
620
621 for (i = 0; i < queue->limit; i++) { 600 for (i = 0; i < queue->limit; i++) {
622 queue->entries[i].flags = 0; 601 queue->entries[i].flags = 0;
623 602
624 rt2x00dev->ops->lib->init_txentry(rt2x00dev, 603 rt2x00dev->ops->lib->clear_entry(&queue->entries[i]);
625 &queue->entries[i]);
626 } 604 }
627 } 605 }
628} 606}
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index b73a7e0aeed4..4eb550fab2f6 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -351,28 +351,25 @@ EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio);
351/* 351/*
352 * Device initialization handlers. 352 * Device initialization handlers.
353 */ 353 */
354void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev, 354void rt2x00usb_clear_entry(struct queue_entry *entry)
355 struct queue_entry *entry)
356{ 355{
357 struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); 356 struct usb_device *usb_dev =
357 to_usb_device_intf(entry->queue->rt2x00dev->dev);
358 struct queue_entry_priv_usb *entry_priv = entry->priv_data; 358 struct queue_entry_priv_usb *entry_priv = entry->priv_data;
359 359
360 usb_fill_bulk_urb(entry_priv->urb, usb_dev, 360 if (entry->queue->qid == QID_RX) {
361 usb_rcvbulkpipe(usb_dev, 1), 361 usb_fill_bulk_urb(entry_priv->urb, usb_dev,
362 entry->skb->data, entry->skb->len, 362 usb_rcvbulkpipe(usb_dev, 1),
363 rt2x00usb_interrupt_rxdone, entry); 363 entry->skb->data, entry->skb->len,
364 rt2x00usb_interrupt_rxdone, entry);
364 365
365 set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); 366 set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
366 usb_submit_urb(entry_priv->urb, GFP_ATOMIC); 367 usb_submit_urb(entry_priv->urb, GFP_ATOMIC);
367} 368 } else {
368EXPORT_SYMBOL_GPL(rt2x00usb_init_rxentry); 369 entry->flags = 0;
369 370 }
370void rt2x00usb_init_txentry(struct rt2x00_dev *rt2x00dev,
371 struct queue_entry *entry)
372{
373 entry->flags = 0;
374} 371}
375EXPORT_SYMBOL_GPL(rt2x00usb_init_txentry); 372EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry);
376 373
377static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev, 374static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev,
378 struct data_queue *queue) 375 struct data_queue *queue)
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h
index 3b4a67417f95..4104f0e8fa48 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.h
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.h
@@ -286,10 +286,7 @@ void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
286/* 286/*
287 * Device initialization handlers. 287 * Device initialization handlers.
288 */ 288 */
289void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev, 289void rt2x00usb_clear_entry(struct queue_entry *entry);
290 struct queue_entry *entry);
291void rt2x00usb_init_txentry(struct rt2x00_dev *rt2x00dev,
292 struct queue_entry *entry);
293int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev); 290int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev);
294void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev); 291void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev);
295 292
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 3f272793412a..abfe33b5712a 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1261,33 +1261,44 @@ static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data,
1261/* 1261/*
1262 * Initialization functions. 1262 * Initialization functions.
1263 */ 1263 */
1264static void rt61pci_init_rxentry(struct rt2x00_dev *rt2x00dev, 1264static bool rt61pci_get_entry_state(struct queue_entry *entry)
1265 struct queue_entry *entry)
1266{ 1265{
1267 struct queue_entry_priv_pci *entry_priv = entry->priv_data; 1266 struct queue_entry_priv_pci *entry_priv = entry->priv_data;
1268 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
1269 u32 word; 1267 u32 word;
1270 1268
1271 rt2x00_desc_read(entry_priv->desc, 5, &word); 1269 if (entry->queue->qid == QID_RX) {
1272 rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS, 1270 rt2x00_desc_read(entry_priv->desc, 0, &word);
1273 skbdesc->skb_dma);
1274 rt2x00_desc_write(entry_priv->desc, 5, word);
1275 1271
1276 rt2x00_desc_read(entry_priv->desc, 0, &word); 1272 return rt2x00_get_field32(word, RXD_W0_OWNER_NIC);
1277 rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); 1273 } else {
1278 rt2x00_desc_write(entry_priv->desc, 0, word); 1274 rt2x00_desc_read(entry_priv->desc, 0, &word);
1275
1276 return (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) ||
1277 rt2x00_get_field32(word, TXD_W0_VALID));
1278 }
1279} 1279}
1280 1280
1281static void rt61pci_init_txentry(struct rt2x00_dev *rt2x00dev, 1281static void rt61pci_clear_entry(struct queue_entry *entry)
1282 struct queue_entry *entry)
1283{ 1282{
1284 struct queue_entry_priv_pci *entry_priv = entry->priv_data; 1283 struct queue_entry_priv_pci *entry_priv = entry->priv_data;
1284 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
1285 u32 word; 1285 u32 word;
1286 1286
1287 rt2x00_desc_read(entry_priv->desc, 0, &word); 1287 if (entry->queue->qid == QID_RX) {
1288 rt2x00_set_field32(&word, TXD_W0_VALID, 0); 1288 rt2x00_desc_read(entry_priv->desc, 5, &word);
1289 rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); 1289 rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS,
1290 rt2x00_desc_write(entry_priv->desc, 0, word); 1290 skbdesc->skb_dma);
1291 rt2x00_desc_write(entry_priv->desc, 5, word);
1292
1293 rt2x00_desc_read(entry_priv->desc, 0, &word);
1294 rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1);
1295 rt2x00_desc_write(entry_priv->desc, 0, word);
1296 } else {
1297 rt2x00_desc_read(entry_priv->desc, 0, &word);
1298 rt2x00_set_field32(&word, TXD_W0_VALID, 0);
1299 rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0);
1300 rt2x00_desc_write(entry_priv->desc, 0, word);
1301 }
1291} 1302}
1292 1303
1293static int rt61pci_init_queues(struct rt2x00_dev *rt2x00dev) 1304static int rt61pci_init_queues(struct rt2x00_dev *rt2x00dev)
@@ -2722,8 +2733,8 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
2722 .load_firmware = rt61pci_load_firmware, 2733 .load_firmware = rt61pci_load_firmware,
2723 .initialize = rt2x00pci_initialize, 2734 .initialize = rt2x00pci_initialize,
2724 .uninitialize = rt2x00pci_uninitialize, 2735 .uninitialize = rt2x00pci_uninitialize,
2725 .init_rxentry = rt61pci_init_rxentry, 2736 .get_entry_state = rt61pci_get_entry_state,
2726 .init_txentry = rt61pci_init_txentry, 2737 .clear_entry = rt61pci_clear_entry,
2727 .set_device_state = rt61pci_set_device_state, 2738 .set_device_state = rt61pci_set_device_state,
2728 .rfkill_poll = rt61pci_rfkill_poll, 2739 .rfkill_poll = rt61pci_rfkill_poll,
2729 .link_stats = rt61pci_link_stats, 2740 .link_stats = rt61pci_link_stats,
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 767e3c98184c..f2c8d9733c1d 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2313,8 +2313,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
2313 .load_firmware = rt73usb_load_firmware, 2313 .load_firmware = rt73usb_load_firmware,
2314 .initialize = rt2x00usb_initialize, 2314 .initialize = rt2x00usb_initialize,
2315 .uninitialize = rt2x00usb_uninitialize, 2315 .uninitialize = rt2x00usb_uninitialize,
2316 .init_rxentry = rt2x00usb_init_rxentry, 2316 .clear_entry = rt2x00usb_clear_entry,
2317 .init_txentry = rt2x00usb_init_txentry,
2318 .set_device_state = rt73usb_set_device_state, 2317 .set_device_state = rt73usb_set_device_state,
2319 .link_stats = rt73usb_link_stats, 2318 .link_stats = rt73usb_link_stats,
2320 .reset_tuner = rt73usb_reset_tuner, 2319 .reset_tuner = rt73usb_reset_tuner,