linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] rt2x00
@ 2007-11-12 14:02 Ivo van Doorn
  2007-11-12 14:02 ` [PATCH 1/3] rt2x00: Fix chipset revision validation Ivo van Doorn
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Ivo van Doorn @ 2007-11-12 14:02 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, rt2400-devel

Hi John,

Here is a minor update for rt2x00, no version bump this time since
the number of patches is so limited. If possible queue these for 2.6.24.

The first one fixes a bug in the chipset revision detection, where devices
were being accepted by the rt2500usb driver while they should be dropped
(in favour of rt73usb).

The second patch is code cleaning, but the third patch depends on this one.
Finally the first patch fixes the dreadfull "non-free entry in the non-full queue"
queue messages which effectively resulted in the TX shutting down comlpletely
with rt61pci.

Ivo

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/3] rt2x00: Fix chipset revision validation
  2007-11-12 14:02 [PATCH 0/3] rt2x00 Ivo van Doorn
@ 2007-11-12 14:02 ` Ivo van Doorn
  2007-11-12 14:02 ` [PATCH 2/3] rt2x00: Move duplicate code into rt2x00pci_txdone() Ivo van Doorn
  2007-11-12 14:03 ` [PATCH 3/3] rt2x00: Allow rt61 to catch up after a missing tx report Ivo van Doorn
  2 siblings, 0 replies; 4+ messages in thread
From: Ivo van Doorn @ 2007-11-12 14:02 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, rt2400-devel

The validation of the chipset revision was broken
since for rt2500usb and rt73usb different registers
should be read. When rt2500usb was loaded for a rt73
device it would false think the chipset was correct
because the wrong register was read and validated.

This has been fixed by expanding the check to also
see if the first 4 bits of the revision is not-0
(When reading the wrong register offset the returned
value is usually 0 which can be interpreted as invalid)

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2500pci.c |    4 ++--
 drivers/net/wireless/rt2x00/rt2500usb.c |    4 ++--
 drivers/net/wireless/rt2x00/rt2x00.h    |    8 +++++---
 drivers/net/wireless/rt2x00/rt73usb.c   |    2 +-
 4 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index c5a5c43..e6a0c37 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -617,7 +617,7 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev)
 	 * up to version C the link tuning should halt after 20
 	 * seconds.
 	 */
-	if (rt2x00_get_rev(&rt2x00dev->chip) < RT2560_VERSION_D &&
+	if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D &&
 	    rt2x00dev->link.count > 20)
 		return;
 
@@ -627,7 +627,7 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev)
 	 * Chipset versions C and lower should directly continue
 	 * to the dynamic CCA tuning.
 	 */
-	if (rt2x00_get_rev(&rt2x00dev->chip) < RT2560_VERSION_D)
+	if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D)
 		goto dynamic_cca_tune;
 
 	/*
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 43f1e0f..b5a8f82 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -791,7 +791,7 @@ static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev)
 	rt2x00_set_field16(&reg, MAC_CSR1_HOST_READY, 1);
 	rt2500usb_register_write(rt2x00dev, MAC_CSR1, reg);
 
-	if (rt2x00_get_rev(&rt2x00dev->chip) >= RT2570_VERSION_C) {
+	if (rt2x00_rev(&rt2x00dev->chip) >= RT2570_VERSION_C) {
 		rt2500usb_register_read(rt2x00dev, PHY_CSR2, &reg);
 		rt2x00_set_field16(&reg, PHY_CSR2_LNA, 0);
 	} else {
@@ -1299,7 +1299,7 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
 	rt2500usb_register_read(rt2x00dev, MAC_CSR0, &reg);
 	rt2x00_set_chip(rt2x00dev, RT2570, value, reg);
 
-	if (rt2x00_rev(&rt2x00dev->chip, 0xffff0)) {
+	if (!rt2x00_check_rev(&rt2x00dev->chip, 0)) {
 		ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
 		return -ENODEV;
 	}
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 82014d8..12382c3 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -849,14 +849,16 @@ static inline char rt2x00_rf(const struct rt2x00_chip *chipset, const u16 chip)
 	return (chipset->rf == chip);
 }
 
-static inline u16 rt2x00_get_rev(const struct rt2x00_chip *chipset)
+static inline u16 rt2x00_rev(const struct rt2x00_chip *chipset)
 {
 	return chipset->rev;
 }
 
-static inline u16 rt2x00_rev(const struct rt2x00_chip *chipset, const u32 mask)
+static inline u16 rt2x00_check_rev(const struct rt2x00_chip *chipset,
+				   const u32 rev)
 {
-	return chipset->rev & mask;
+	return (((chipset->rev & 0xffff0) == rev) &&
+		!!(chipset->rev & 0x0000f));
 }
 
 /*
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 532e75d..9bd0b4f 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1530,7 +1530,7 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
 	rt73usb_register_read(rt2x00dev, MAC_CSR0, &reg);
 	rt2x00_set_chip(rt2x00dev, RT2571, value, reg);
 
-	if (!rt2x00_rev(&rt2x00dev->chip, 0x25730)) {
+	if (!rt2x00_check_rev(&rt2x00dev->chip, 0x25730)) {
 		ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
 		return -ENODEV;
 	}
-- 
1.5.3.4


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/3] rt2x00: Move duplicate code into rt2x00pci_txdone()
  2007-11-12 14:02 [PATCH 0/3] rt2x00 Ivo van Doorn
  2007-11-12 14:02 ` [PATCH 1/3] rt2x00: Fix chipset revision validation Ivo van Doorn
@ 2007-11-12 14:02 ` Ivo van Doorn
  2007-11-12 14:03 ` [PATCH 3/3] rt2x00: Allow rt61 to catch up after a missing tx report Ivo van Doorn
  2 siblings, 0 replies; 4+ messages in thread
From: Ivo van Doorn @ 2007-11-12 14:02 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, rt2400-devel

rt2400pci, rt2500pci and rt61 require different
txdone handling, but the code that pushes the frame
upstream and cleans up the entry is identical to
all of them.
This will create the function rt2x00pci_txdone()
to remove the duplicate code.

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2400pci.c |   20 +-----------------
 drivers/net/wireless/rt2x00/rt2500pci.c |   20 +-----------------
 drivers/net/wireless/rt2x00/rt2x00pci.c |   33 ++++++++++++++++++++++++++++++-
 drivers/net/wireless/rt2x00/rt2x00pci.h |    4 ++-
 drivers/net/wireless/rt2x00/rt61pci.c   |   19 +----------------
 5 files changed, 38 insertions(+), 58 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index d48b6ca..bdf3edc 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1167,26 +1167,8 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue)
 		tx_status = rt2x00_get_field32(word, TXD_W0_RESULT);
 		retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT);
 
-		rt2x00lib_txdone(entry, tx_status, retry);
-
-		/*
-		 * Make this entry available for reuse.
-		 */
-		entry->flags = 0;
-		rt2x00_set_field32(&word, TXD_W0_VALID, 0);
-		rt2x00_desc_write(txd, 0, word);
-		rt2x00_ring_index_done_inc(ring);
+		rt2x00pci_txdone(rt2x00dev, entry, tx_status, retry);
 	}
-
-	/*
-	 * If the data ring was full before the txdone handler
-	 * we must make sure the packet queue in the mac80211 stack
-	 * is reenabled when the txdone handler has finished.
-	 */
-	entry = ring->entry;
-	if (!rt2x00_ring_full(ring))
-		ieee80211_wake_queue(rt2x00dev->hw,
-				     entry->tx_status.control.queue);
 }
 
 static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance)
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index e6a0c37..b6bb964 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1298,26 +1298,8 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, const int queue)
 		tx_status = rt2x00_get_field32(word, TXD_W0_RESULT);
 		retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT);
 
-		rt2x00lib_txdone(entry, tx_status, retry);
-
-		/*
-		 * Make this entry available for reuse.
-		 */
-		entry->flags = 0;
-		rt2x00_set_field32(&word, TXD_W0_VALID, 0);
-		rt2x00_desc_write(txd, 0, word);
-		rt2x00_ring_index_done_inc(ring);
+		rt2x00pci_txdone(rt2x00dev, entry, tx_status, retry);
 	}
-
-	/*
-	 * If the data ring was full before the txdone handler
-	 * we must make sure the packet queue in the mac80211 stack
-	 * is reenabled when the txdone handler has finished.
-	 */
-	entry = ring->entry;
-	if (!rt2x00_ring_full(ring))
-		ieee80211_wake_queue(rt2x00dev->hw,
-				     entry->tx_status.control.queue);
 }
 
 static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance)
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 045b954..30ef4f9 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -116,7 +116,7 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev,
 EXPORT_SYMBOL_GPL(rt2x00pci_write_tx_data);
 
 /*
- * RX data handlers.
+ * TX/RX data handlers.
  */
 void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
 {
@@ -165,6 +165,37 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
 }
 EXPORT_SYMBOL_GPL(rt2x00pci_rxdone);
 
+void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct data_entry *entry,
+		      const int tx_status, const int retry)
+{
+	u32 word;
+
+	rt2x00lib_txdone(entry, tx_status, retry);
+
+	/*
+	 * Make this entry available for reuse.
+	 */
+	entry->flags = 0;
+
+	rt2x00_desc_read(entry->priv, 0, &word);
+	rt2x00_set_field32(&word, TXD_ENTRY_OWNER_NIC, 0);
+	rt2x00_set_field32(&word, TXD_ENTRY_VALID, 0);
+	rt2x00_desc_write(entry->priv, 0, word);
+
+	rt2x00_ring_index_done_inc(entry->ring);
+
+	/*
+	 * If the data ring was full before the txdone handler
+	 * we must make sure the packet queue in the mac80211 stack
+	 * is reenabled when the txdone handler has finished.
+	 */
+	if (!rt2x00_ring_full(entry->ring))
+		ieee80211_wake_queue(rt2x00dev->hw,
+				     entry->tx_status.control.queue);
+
+}
+EXPORT_SYMBOL_GPL(rt2x00pci_txdone);
+
 /*
  * Device initialization handlers.
  */
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h
index 0357205..2d1eb81 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.h
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.h
@@ -101,9 +101,11 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev,
 			    struct ieee80211_tx_control *control);
 
 /*
- * RX data handlers.
+ * RX/TX data handlers.
  */
 void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev);
+void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct data_entry *entry,
+		      const int tx_status, const int retry);
 
 /*
  * Device initialization handlers.
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 105dc86..a6d4e10 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1767,24 +1767,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
 		tx_status = rt2x00_get_field32(reg, STA_CSR4_TX_RESULT);
 		retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT);
 
-		rt2x00lib_txdone(entry, tx_status, retry);
-
-		/*
-		 * Make this entry available for reuse.
-		 */
-		entry->flags = 0;
-		rt2x00_set_field32(&word, TXD_W0_VALID, 0);
-		rt2x00_desc_write(txd, 0, word);
-		rt2x00_ring_index_done_inc(entry->ring);
-
-		/*
-		 * If the data ring was full before the txdone handler
-		 * we must make sure the packet queue in the mac80211 stack
-		 * is reenabled when the txdone handler has finished.
-		 */
-		if (!rt2x00_ring_full(ring))
-			ieee80211_wake_queue(rt2x00dev->hw,
-					     entry->tx_status.control.queue);
+		rt2x00pci_txdone(rt2x00dev, entry, tx_status, retry);
 	}
 }
 
-- 
1.5.3.4


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 3/3] rt2x00: Allow rt61 to catch up after a missing tx report
  2007-11-12 14:02 [PATCH 0/3] rt2x00 Ivo van Doorn
  2007-11-12 14:02 ` [PATCH 1/3] rt2x00: Fix chipset revision validation Ivo van Doorn
  2007-11-12 14:02 ` [PATCH 2/3] rt2x00: Move duplicate code into rt2x00pci_txdone() Ivo van Doorn
@ 2007-11-12 14:03 ` Ivo van Doorn
  2 siblings, 0 replies; 4+ messages in thread
From: Ivo van Doorn @ 2007-11-12 14:03 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, rt2400-devel

From: Mattias Nissler <mattias.nissler@gmx.de>

Sometimes it happens in the tx path that an entry given to the hardware isn't
reported in the txdone handler. This ultimately led to the dreaded "non-free
entry in the non-full queue" message and the stopping of the tx queue. Work
around this issue by allowing the driver to also clear out previos entries in
the txdone handler.

Signed-off-by: Mattias Nissler <mattias.nissler@gmx.de>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
 drivers/net/wireless/rt2x00/rt61pci.c |   13 +++++++++++++
 1 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index a6d4e10..c2b4509 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1708,6 +1708,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
 {
 	struct data_ring *ring;
 	struct data_entry *entry;
+	struct data_entry *entry_done;
 	__le32 *txd;
 	u32 word;
 	u32 reg;
@@ -1761,6 +1762,18 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
 		    !rt2x00_get_field32(word, TXD_W0_VALID))
 			return;
 
+		entry_done = rt2x00_get_data_entry_done(ring);
+		while (entry != entry_done) {
+			/* Catch up. Just report any entries we missed as
+			 * failed. */
+			WARNING(rt2x00dev,
+				"TX status report missed for entry %p\n",
+				entry_done);
+			rt2x00pci_txdone(rt2x00dev, entry_done, TX_FAIL_OTHER,
+					 0);
+			entry_done = rt2x00_get_data_entry_done(ring);
+		}
+
 		/*
 		 * Obtain the status about this packet.
 		 */
-- 
1.5.3.4


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2007-11-12 13:49 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-11-12 14:02 [PATCH 0/3] rt2x00 Ivo van Doorn
2007-11-12 14:02 ` [PATCH 1/3] rt2x00: Fix chipset revision validation Ivo van Doorn
2007-11-12 14:02 ` [PATCH 2/3] rt2x00: Move duplicate code into rt2x00pci_txdone() Ivo van Doorn
2007-11-12 14:03 ` [PATCH 3/3] rt2x00: Allow rt61 to catch up after a missing tx report Ivo van Doorn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).