linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/24] rt2x00: Remove firmware not-NULL check
       [not found] <200709161403.11332.IvDoorn@gmail.com>
@ 2007-09-16 12:17 ` Ivo van Doorn
  2007-09-16 12:17 ` [PATCH 2/24] rt2x00: Don't check for IEEE80211_TXCTL_REQ_TX_STATUS Ivo van Doorn
                   ` (22 subsequent siblings)
  23 siblings, 0 replies; 24+ messages in thread
From: Ivo van Doorn @ 2007-09-16 12:17 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, rt2400-devel

When cleaning up the firmware, we don't need
to check if rt2x00dev->fw is not-NULL.

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2x00firmware.c |    6 ++----
 1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2x00firmware.c b/drivers/net/wireless/rt2x00/rt2x00firmware.c
index 143e793..236025f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00firmware.c
+++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c
@@ -118,9 +118,7 @@ int rt2x00lib_load_firmware(struct rt2x00_dev *rt2x00dev)
 
 void rt2x00lib_free_firmware(struct rt2x00_dev *rt2x00dev)
 {
-	if (rt2x00dev->fw) {
-		release_firmware(rt2x00dev->fw);
-		rt2x00dev->fw = NULL;
-	}
+	release_firmware(rt2x00dev->fw);
+	rt2x00dev->fw = NULL;
 }
 
-- 
1.5.3

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

* [PATCH 2/24] rt2x00: Don't check for IEEE80211_TXCTL_REQ_TX_STATUS
       [not found] <200709161403.11332.IvDoorn@gmail.com>
  2007-09-16 12:17 ` [PATCH 1/24] rt2x00: Remove firmware not-NULL check Ivo van Doorn
@ 2007-09-16 12:17 ` Ivo van Doorn
  2007-09-16 12:18 ` [PATCH 3/24] rt2x00: Cleanup rxdone Ivo van Doorn
                   ` (21 subsequent siblings)
  23 siblings, 0 replies; 24+ messages in thread
From: Ivo van Doorn @ 2007-09-16 12:17 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, rt2400-devel

As recommended by Johannes Berg, rt2x00 shouldn't check
for IEEE80211_TXCTL_REQ_TX_STATUS and always pass the frame
back to mac80211.

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2x00dev.c |   12 +++---------
 1 files changed, 3 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 8c24797..c4086f0 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -333,16 +333,10 @@ void rt2x00lib_txdone(struct data_entry *entry,
 	}
 
 	/*
-	 * Check if mac80211 wants to be updated or not,
-	 * if it wants the update it will cleanup the skb structure,
-	 * else then we should cleanup the skb structure.
+	 * Send the tx_status to mac80211,
+	 * that method also cleans up the skb structure.
 	 */
-	if (tx_status->control.flags & IEEE80211_TXCTL_REQ_TX_STATUS)
-		ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb,
-					    tx_status);
-	else
-		dev_kfree_skb_any(entry->skb);
-
+	ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb, tx_status);
 	entry->skb = NULL;
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_txdone);
-- 
1.5.3

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

* [PATCH 3/24] rt2x00: Cleanup rxdone
       [not found] <200709161403.11332.IvDoorn@gmail.com>
  2007-09-16 12:17 ` [PATCH 1/24] rt2x00: Remove firmware not-NULL check Ivo van Doorn
  2007-09-16 12:17 ` [PATCH 2/24] rt2x00: Don't check for IEEE80211_TXCTL_REQ_TX_STATUS Ivo van Doorn
@ 2007-09-16 12:18 ` Ivo van Doorn
  2007-09-16 12:18 ` [PATCH 4/24] rt2x00: Don't allow configuration calls when uninitialized Ivo van Doorn
                   ` (20 subsequent siblings)
  23 siblings, 0 replies; 24+ messages in thread
From: Ivo van Doorn @ 2007-09-16 12:18 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, rt2400-devel

Remove obscure skb allocation with rt2x00lib_rxdone,
and move the allocation into rt2x00pci and rt2x00usb.
Allocation handling is different between PCI and USB
devices and to make the differences more clear they
should be handled within the correct modules.

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2x00.h    |    5 ++---
 drivers/net/wireless/rt2x00/rt2x00dev.c |   27 ++++-----------------------
 drivers/net/wireless/rt2x00/rt2x00pci.c |   18 +++++++++++++++---
 drivers/net/wireless/rt2x00/rt2x00usb.c |   26 +++++++++++++++++++++++---
 4 files changed, 44 insertions(+), 32 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 2105f44..a7527cd 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -742,9 +742,8 @@ struct data_ring *rt2x00lib_get_ring(struct rt2x00_dev *rt2x00dev,
 void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev);
 void rt2x00lib_txdone(struct data_entry *entry,
 		      const int status, const int retry);
-void rt2x00lib_rxdone(struct data_entry *entry, char *data,
-		      const int size, const int signal,
-		      const int rssi, const int ofdm);
+void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb,
+		      const int signal, const int rssi, const int ofdm);
 
 /*
  * TX descriptor initializer
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index c4086f0..f2adaf5 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -341,15 +341,13 @@ void rt2x00lib_txdone(struct data_entry *entry,
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_txdone);
 
-void rt2x00lib_rxdone(struct data_entry *entry, char *data,
-		      const int size, const int signal,
-		      const int rssi, const int ofdm)
+void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb,
+		      const int signal, const int rssi, const int ofdm)
 {
 	struct rt2x00_dev *rt2x00dev = entry->ring->rt2x00dev;
 	struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status;
 	struct ieee80211_hw_mode *mode;
 	struct ieee80211_rate *rate;
-	struct sk_buff *skb;
 	unsigned int i;
 	int val = 0;
 
@@ -383,26 +381,9 @@ void rt2x00lib_rxdone(struct data_entry *entry, char *data,
 	rx_status->ssi = rssi;
 
 	/*
-	 * Let's allocate a sk_buff where we can store the received data in,
-	 * note that if data is NULL, we still have to allocate a sk_buff
-	 * but that we should use that to replace the sk_buff which is already
-	 * inside the entry.
+	 * Send frame to mac80211
 	 */
-	skb = dev_alloc_skb(size + NET_IP_ALIGN);
-	if (!skb)
-		return;
-
-	skb_reserve(skb, NET_IP_ALIGN);
-	skb_put(skb, size);
-
-	if (data) {
-		memcpy(skb->data, data, size);
-		entry->skb = skb;
-		skb = NULL;
-	}
-
-	ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb, rx_status);
-	entry->skb = skb;
+	ieee80211_rx_irqsafe(rt2x00dev->hw, skb, rx_status);
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_rxdone);
 
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index c54b30f..66fce58 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -123,6 +123,7 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
 	struct data_ring *ring = rt2x00dev->rx;
 	struct data_entry *entry;
 	struct data_desc *rxd;
+	struct sk_buff *skb;
 	u32 desc;
 	int retval;
 	int signal;
@@ -144,10 +145,21 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
 			goto skip_entry;
 
 		/*
-		 * Send the packet to upper layer.
+		 * Allocate the sk_buffer, initialize it and copy
+		 * all data into it.
 		 */
-		rt2x00lib_rxdone(entry, entry->data_addr, size,
-				 signal, rssi, ofdm);
+		skb = dev_alloc_skb(size + NET_IP_ALIGN);
+		if (!skb)
+			return;
+
+		skb_reserve(skb, NET_IP_ALIGN);
+		skb_put(skb, size);
+		memcpy(skb->data, entry->data_addr, size);
+
+		/*
+		 * Send the frame to rt2x00lib for further processing.
+		 */
+		rt2x00lib_rxdone(entry, skb, signal, rssi, ofdm);
 
 skip_entry:
 		if (test_bit(DEVICE_ENABLED_RADIO, &ring->rt2x00dev->flags)) {
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 03815b6..31ef87a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -327,11 +327,13 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
 	struct data_entry *entry = (struct data_entry *)urb->context;
 	struct data_ring *ring = entry->ring;
 	struct rt2x00_dev *rt2x00dev = ring->rt2x00dev;
+	struct sk_buff *skb;
 	int retval;
 	int signal;
 	int rssi;
 	int ofdm;
 	int size;
+	int frame_size;
 
 	if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) ||
 	    !test_and_clear_bit(ENTRY_OWNER_NIC, &entry->flags))
@@ -351,16 +353,34 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
 		goto skip_entry;
 
 	/*
+	 * Allocate a new sk buffer to replace the current one.
+	 * If allocation fails, we should drop the current frame
+	 * so we can recycle the existing sk buffer for the new frame.
+	 */
+	frame_size = entry->ring->data_size + entry->ring->desc_size;
+	skb = dev_alloc_skb(frame_size + NET_IP_ALIGN);
+	if (!skb)
+		goto skip_entry;
+
+	skb_reserve(skb, NET_IP_ALIGN);
+	skb_put(skb, frame_size);
+
+	/*
 	 * Trim the skb_buffer to only contain the valid
 	 * frame data (so ignore the device's descriptor).
 	 */
 	skb_trim(entry->skb, size);
 
 	/*
-	 * Send the packet to upper layer, and update urb.
+	 * Send the frame to rt2x00lib for further processing.
 	 */
-	rt2x00lib_rxdone(entry, NULL, ring->data_size + ring->desc_size,
-			 signal, rssi, ofdm);
+	rt2x00lib_rxdone(entry, entry->skb, signal, rssi, ofdm);
+
+	/*
+	 * Replace current entry's skb with the newly allocated one,
+	 * and reinitialize the urb.
+	 */
+	entry->skb = skb;
 	urb->transfer_buffer = entry->skb->data;
 	urb->transfer_buffer_length = entry->skb->len;
 
-- 
1.5.3

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

* [PATCH 4/24] rt2x00: Don't allow configuration calls when uninitialized
       [not found] <200709161403.11332.IvDoorn@gmail.com>
                   ` (2 preceding siblings ...)
  2007-09-16 12:18 ` [PATCH 3/24] rt2x00: Cleanup rxdone Ivo van Doorn
@ 2007-09-16 12:18 ` Ivo van Doorn
  2007-09-16 12:18 ` [PATCH 5/24] rt2x00: Fix rt61pci and rt73usb beacon handling Ivo van Doorn
                   ` (19 subsequent siblings)
  23 siblings, 0 replies; 24+ messages in thread
From: Ivo van Doorn @ 2007-09-16 12:18 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, rt2400-devel

When a device is being hot-unplugged or during suspend/resume
rt2x00 is not able to handle configuration calls from mac80211.
Check for the DEVICE_INITIALIZED flag to determine if a
configuration call from mac80211 is welcome or not.

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2x00mac.c |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index f25cf38..0001b79 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -245,6 +245,15 @@ int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
 	struct rt2x00_dev *rt2x00dev = hw->priv;
 
 	/*
+	 * If the device is not initialized we shouldn't accept
+	 * any configuration changes. Mac80211 might be calling
+	 * this function while we are trying to remove the device
+	 * or perhaps suspending it.
+	 */
+	if (!test_bit(DEVICE_INITIALIZED, &rt2x00dev->flags))
+		return 0;
+
+	/*
 	 * Check if we need to disable the radio,
 	 * if this is not the case, at least the RX must be disabled.
 	 */
@@ -285,6 +294,15 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw, int if_id,
 	int status;
 
 	/*
+	 * If the device is not initialized we shouldn't accept
+	 * any configuration changes. Mac80211 might be calling
+	 * this function while we are trying to remove the device
+	 * or perhaps suspending it.
+	 */
+	if (!test_bit(DEVICE_INITIALIZED, &rt2x00dev->flags))
+		return 0;
+
+	/*
 	 * Monitor mode does not need configuring.
 	 * If the given type does not match the configured type,
 	 * there has been a problem.
-- 
1.5.3

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

* [PATCH 5/24] rt2x00: Fix rt61pci and rt73usb beacon handling
       [not found] <200709161403.11332.IvDoorn@gmail.com>
                   ` (3 preceding siblings ...)
  2007-09-16 12:18 ` [PATCH 4/24] rt2x00: Don't allow configuration calls when uninitialized Ivo van Doorn
@ 2007-09-16 12:18 ` Ivo van Doorn
  2007-09-16 12:18 ` [PATCH 6/24] rt2x00: Recalculate link quality Ivo van Doorn
                   ` (18 subsequent siblings)
  23 siblings, 0 replies; 24+ messages in thread
From: Ivo van Doorn @ 2007-09-16 12:18 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, rt2400-devel

Beacon handling in rt61pci and rt73usb is completely
different compared to older chipsets.
These devices have 4 slots for Beacons to which
the beacon should be written. The entire beacon
including the decsriptor needs to be written to
a particular slot and beacon generator needs to
be kicked afterwards.

Because the CSR cache size is limited (8 bytes),
we cannot use it to write the beacon to the device.
Because of that we need to use rt2x00usb_vendor_request()
instead of rt73usb_register_multiwrite() to bybass the cache usage.
This should be safe, since skb->data is allocated using
kmalloc() or friend.

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2500usb.c |  109 ++++++++++++++++++++++++++++++-
 drivers/net/wireless/rt2x00/rt2x00usb.c |  107 ------------------------------
 drivers/net/wireless/rt2x00/rt2x00usb.h |    6 --
 drivers/net/wireless/rt2x00/rt61pci.c   |   77 +++++++++++++++++++---
 drivers/net/wireless/rt2x00/rt73usb.c   |   57 ++++++++++++++++-
 5 files changed, 230 insertions(+), 126 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index dc247c4..06219ce 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1139,6 +1139,38 @@ static int rt2500usb_fill_rxdone(struct data_entry *entry,
 }
 
 /*
+ * Interrupt functions.
+ */
+static void rt2500usb_beacondone(struct urb *urb)
+{
+	struct data_entry *entry = (struct data_entry *)urb->context;
+	struct data_ring *ring = entry->ring;
+
+	if (!test_bit(DEVICE_ENABLED_RADIO, &ring->rt2x00dev->flags))
+		return;
+
+	/*
+	 * Check if this was the guardian beacon,
+	 * if that was the case we need to send the real beacon now.
+	 * Otherwise we should free the sk_buffer, the device
+	 * should be doing the rest of the work now.
+	 */
+	if (ring->index == 1) {
+		rt2x00_ring_index_done_inc(ring);
+		entry = rt2x00_get_data_entry(ring);
+		usb_submit_urb(entry->priv, GFP_ATOMIC);
+		rt2x00_ring_index_inc(ring);
+	} else if (ring->index_done == 1) {
+		entry = rt2x00_get_data_entry_done(ring);
+		if (entry->skb) {
+			dev_kfree_skb(entry->skb);
+			entry->skb = NULL;
+		}
+		rt2x00_ring_index_done_inc(ring);
+	}
+}
+
+/*
  * Device probe functions.
  */
 static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)
@@ -1556,6 +1588,81 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
 /*
  * IEEE80211 stack callback functions.
  */
+static int rt2500usb_beacon_update(struct ieee80211_hw *hw,
+				   struct sk_buff *skb,
+				   struct ieee80211_tx_control *control)
+{
+	struct rt2x00_dev *rt2x00dev = hw->priv;
+	struct usb_device *usb_dev =
+	    interface_to_usbdev(rt2x00dev_usb(rt2x00dev));
+	struct data_ring *ring =
+	    rt2x00lib_get_ring(rt2x00dev, IEEE80211_TX_QUEUE_BEACON);
+	struct data_entry *beacon;
+	struct data_entry *guardian;
+	int length;
+
+	/*
+	 * Just in case the ieee80211 doesn't set this,
+	 * but we need this queue set for the descriptor
+	 * initialization.
+	 */
+	control->queue = IEEE80211_TX_QUEUE_BEACON;
+
+	/*
+	 * Obtain 2 entries, one for the guardian byte,
+	 * the second for the actual beacon.
+	 */
+	guardian = rt2x00_get_data_entry(ring);
+	rt2x00_ring_index_inc(ring);
+	beacon = rt2x00_get_data_entry(ring);
+
+	/*
+	 * First we create the beacon.
+	 */
+	skb_push(skb, ring->desc_size);
+	rt2x00lib_write_tx_desc(rt2x00dev, beacon,
+				(struct data_desc *)skb->data,
+				(struct ieee80211_hdr *)(skb->data +
+							 ring->desc_size),
+				skb->len - ring->desc_size, control);
+
+	/*
+	 * Length passed to usb_fill_urb cannot be an odd number,
+	 * so add 1 byte to make it even.
+	 */
+	length = skb->len;
+	if (length % 2)
+		length++;
+
+	usb_fill_bulk_urb(beacon->priv, usb_dev,
+			  usb_sndbulkpipe(usb_dev, 1),
+			  skb->data, length, rt2500usb_beacondone, beacon);
+
+	beacon->skb = skb;
+
+	/*
+	 * Second we need to create the guardian byte.
+	 * We only need a single byte, so lets recycle
+	 * the 'flags' field we are not using for beacons.
+	 */
+	guardian->flags = 0;
+	usb_fill_bulk_urb(guardian->priv, usb_dev,
+			  usb_sndbulkpipe(usb_dev, 1),
+			  &guardian->flags, 1, rt2500usb_beacondone, guardian);
+
+	/*
+	 * Send out the guardian byte.
+	 */
+	usb_submit_urb(guardian->priv, GFP_ATOMIC);
+
+	/*
+	 * Enable beacon generation.
+	 */
+	rt2500usb_kick_tx_queue(rt2x00dev, IEEE80211_TX_QUEUE_BEACON);
+
+	return 0;
+}
+
 static const struct ieee80211_ops rt2500usb_mac80211_ops = {
 	.tx			= rt2x00mac_tx,
 	.add_interface		= rt2x00mac_add_interface,
@@ -1566,7 +1673,7 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = {
 	.get_stats		= rt2x00mac_get_stats,
 	.conf_tx		= rt2x00mac_conf_tx,
 	.get_tx_stats		= rt2x00mac_get_tx_stats,
-	.beacon_update		= rt2x00usb_beacon_update,
+	.beacon_update		= rt2500usb_beacon_update,
 };
 
 static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 31ef87a..246ba93 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -108,113 +108,6 @@ int rt2x00usb_vendor_request_buff(const struct rt2x00_dev *rt2x00dev,
 EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff);
 
 /*
- * Beacon handlers.
- */
-static void rt2x00usb_beacondone(struct urb *urb)
-{
-	struct data_entry *entry = (struct data_entry *)urb->context;
-	struct data_ring *ring = entry->ring;
-
-	if (!test_bit(DEVICE_ENABLED_RADIO, &ring->rt2x00dev->flags))
-		return;
-
-	/*
-	 * Check if this was the guardian beacon,
-	 * if that was the case we need to send the real beacon now.
-	 * Otherwise we should free the sk_buffer, the device
-	 * should be doing the rest of the work now.
-	 */
-	if (ring->index == 1) {
-		rt2x00_ring_index_done_inc(ring);
-		entry = rt2x00_get_data_entry(ring);
-		usb_submit_urb(entry->priv, GFP_ATOMIC);
-		rt2x00_ring_index_inc(ring);
-	} else if (ring->index_done == 1) {
-		entry = rt2x00_get_data_entry_done(ring);
-		if (entry->skb) {
-			dev_kfree_skb(entry->skb);
-			entry->skb = NULL;
-		}
-		rt2x00_ring_index_done_inc(ring);
-	}
-}
-
-int rt2x00usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
-			    struct ieee80211_tx_control *control)
-{
-	struct rt2x00_dev *rt2x00dev = hw->priv;
-	struct usb_device *usb_dev =
-	    interface_to_usbdev(rt2x00dev_usb(rt2x00dev));
-	struct data_ring *ring =
-	    rt2x00lib_get_ring(rt2x00dev, IEEE80211_TX_QUEUE_BEACON);
-	struct data_entry *beacon;
-	struct data_entry *guardian;
-	int length;
-
-	/*
-	 * Just in case the ieee80211 doesn't set this,
-	 * but we need this queue set for the descriptor
-	 * initialization.
-	 */
-	control->queue = IEEE80211_TX_QUEUE_BEACON;
-
-	/*
-	 * Obtain 2 entries, one for the guardian byte,
-	 * the second for the actual beacon.
-	 */
-	guardian = rt2x00_get_data_entry(ring);
-	rt2x00_ring_index_inc(ring);
-	beacon = rt2x00_get_data_entry(ring);
-
-	/*
-	 * First we create the beacon.
-	 */
-	skb_push(skb, ring->desc_size);
-	rt2x00lib_write_tx_desc(rt2x00dev, beacon,
-				(struct data_desc *)skb->data,
-				(struct ieee80211_hdr *)(skb->data +
-							 ring->desc_size),
-				skb->len - ring->desc_size, control);
-
-	/*
-	 * Length passed to usb_fill_urb cannot be an odd number,
-	 * so add 1 byte to make it even.
-	 */
-	length = skb->len;
-	if (length % 2)
-		length++;
-
-	usb_fill_bulk_urb(beacon->priv, usb_dev,
-			  usb_sndbulkpipe(usb_dev, 1),
-			  skb->data, length, rt2x00usb_beacondone, beacon);
-
-	beacon->skb = skb;
-
-	/*
-	 * Second we need to create the guardian byte.
-	 * We only need a single byte, so lets recycle
-	 * the 'flags' field we are not using for beacons.
-	 */
-	guardian->flags = 0;
-	usb_fill_bulk_urb(guardian->priv, usb_dev,
-			  usb_sndbulkpipe(usb_dev, 1),
-			  &guardian->flags, 1, rt2x00usb_beacondone, guardian);
-
-	/*
-	 * Send out the guardian byte.
-	 */
-	usb_submit_urb(guardian->priv, GFP_ATOMIC);
-
-	/*
-	 * Enable beacon generation.
-	 */
-	rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, control->queue);
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(rt2x00usb_beacon_update);
-
-/*
  * TX data handlers.
  */
 static void rt2x00usb_interrupt_txdone(struct urb *urb)
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h
index eb410d2..f3be092 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.h
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.h
@@ -151,12 +151,6 @@ void rt2x00usb_enable_radio(struct rt2x00_dev *rt2x00dev);
 void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev);
 
 /*
- * Beacon handlers.
- */
-int rt2x00usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
-			    struct ieee80211_tx_control *control);
-
-/*
  * TX data handlers.
  */
 int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 7a0ba33..fe9edb9 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -331,7 +331,17 @@ static void rt61pci_config_type(struct rt2x00_dev *rt2x00dev, const int type)
 {
 	u32 reg;
 
+	/*
+	 * Clear current synchronisation setup.
+	 * For the Beacon base registers we only need to clear
+	 * the first byte since that byte contains the VALID and OWNER
+	 * bits which (when set to 0) will invalidate the entire beacon.
+	 */
 	rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0);
+	rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE0, 0);
+	rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE1, 0);
+	rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE2, 0);
+	rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE3, 0);
 
 	/*
 	 * Apply hardware packet filter.
@@ -1332,7 +1342,6 @@ static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
 	rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, &reg);
 	rt2x00_set_field32(&reg, INT_MASK_CSR_TXDONE, mask);
 	rt2x00_set_field32(&reg, INT_MASK_CSR_RXDONE, mask);
-	rt2x00_set_field32(&reg, INT_MASK_CSR_BEACON_DONE, mask);
 	rt2x00_set_field32(&reg, INT_MASK_CSR_ENABLE_MITIGATION, mask);
 	rt2x00_set_field32(&reg, INT_MASK_CSR_MITIGATION_PERIOD, 0xff);
 	rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg);
@@ -1550,6 +1559,12 @@ static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
 	u32 reg;
 
 	if (queue == IEEE80211_TX_QUEUE_BEACON) {
+		/*
+		 * For Wi-Fi faily generated beacons between participating
+		 * stations. Set TBTT phase adaptive adjustment step to 8us.
+		 */
+		rt2x00pci_register_write(rt2x00dev, TXRX_CSR10, 0x00001008);
+
 		rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
 		if (!rt2x00_get_field32(reg, TXRX_CSR9_BEACON_GEN)) {
 			rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 1);
@@ -1743,25 +1758,19 @@ static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance)
 	 */
 
 	/*
-	 * 1 - Beacon timer expired interrupt.
-	 */
-	if (rt2x00_get_field32(reg, INT_SOURCE_CSR_BEACON_DONE))
-		rt2x00lib_beacondone(rt2x00dev);
-
-	/*
-	 * 2 - Rx ring done interrupt.
+	 * 1 - Rx ring done interrupt.
 	 */
 	if (rt2x00_get_field32(reg, INT_SOURCE_CSR_RXDONE))
 		rt2x00pci_rxdone(rt2x00dev);
 
 	/*
-	 * 3 - Tx ring done interrupt.
+	 * 2 - Tx ring done interrupt.
 	 */
 	if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TXDONE))
 		rt61pci_txdone(rt2x00dev);
 
 	/*
-	 * 4 - Handle MCU command done.
+	 * 3 - Handle MCU command done.
 	 */
 	if (reg_mcu)
 		rt2x00pci_register_write(rt2x00dev,
@@ -2119,6 +2128,7 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
 	 * Initialize all hw fields.
 	 */
 	rt2x00dev->hw->flags =
+	    IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
 	    IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
 	    IEEE80211_HW_MONITOR_DURING_OPER |
 	    IEEE80211_HW_NO_PROBE_FILTERING;
@@ -2241,6 +2251,51 @@ static void rt61pci_reset_tsf(struct ieee80211_hw *hw)
 	rt2x00pci_register_write(rt2x00dev, TXRX_CSR13, 0);
 }
 
+int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
+			  struct ieee80211_tx_control *control)
+{
+	struct rt2x00_dev *rt2x00dev = hw->priv;
+	struct data_ring *ring =
+	    rt2x00lib_get_ring(rt2x00dev, IEEE80211_TX_QUEUE_BEACON);
+
+	/*
+	 * Just in case the ieee80211 doesn't set this,
+	 * but we need this queue set for the descriptor
+	 * initialization.
+	 */
+	control->queue = IEEE80211_TX_QUEUE_BEACON;
+
+	/*
+	 * We need to append the descriptor in front of the
+	 * beacon frame.
+	 */
+	if (skb_headroom(skb) < ring->desc_size) {
+		if (pskb_expand_head(skb, ring->desc_size, 0, GFP_ATOMIC)) {
+			dev_kfree_skb(skb);
+			return -ENOMEM;
+		}
+	}
+
+	/*
+	 * First we create the beacon.
+	 */
+	skb_push(skb, ring->desc_size);
+	rt2x00lib_write_tx_desc(rt2x00dev, ring->entry,
+				(struct data_desc *)skb->data,
+				(struct ieee80211_hdr *)(skb->data +
+							 ring->desc_size),
+				skb->len - ring->desc_size, control);
+
+	/*
+	 * Write entire beacon with descriptor to register,
+	 * and kick the beacon generator.
+	 */
+	rt2x00pci_register_multiwrite(rt2x00dev, HW_BEACON_BASE0, skb->data, skb->len);
+	rt61pci_kick_tx_queue(rt2x00dev, IEEE80211_TX_QUEUE_BEACON);
+
+	return 0;
+}
+
 static const struct ieee80211_ops rt61pci_mac80211_ops = {
 	.tx			= rt2x00mac_tx,
 	.add_interface		= rt2x00mac_add_interface,
@@ -2254,7 +2309,7 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = {
 	.get_tx_stats		= rt2x00mac_get_tx_stats,
 	.get_tsf		= rt61pci_get_tsf,
 	.reset_tsf		= rt61pci_reset_tsf,
-	.beacon_update		= rt2x00pci_beacon_update,
+	.beacon_update		= rt61pci_beacon_update,
 };
 
 static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 9a08d49..78c15f4 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -312,7 +312,17 @@ static void rt73usb_config_type(struct rt2x00_dev *rt2x00dev, const int type)
 {
 	u32 reg;
 
+	/*
+	 * Clear current synchronisation setup.
+	 * For the Beacon base registers we only need to clear
+	 * the first byte since that byte contains the VALID and OWNER
+	 * bits which (when set to 0) will invalidate the entire beacon.
+	 */
 	rt73usb_register_write(rt2x00dev, TXRX_CSR9, 0);
+	rt73usb_register_write(rt2x00dev, HW_BEACON_BASE0, 0);
+	rt73usb_register_write(rt2x00dev, HW_BEACON_BASE1, 0);
+	rt73usb_register_write(rt2x00dev, HW_BEACON_BASE2, 0);
+	rt73usb_register_write(rt2x00dev, HW_BEACON_BASE3, 0);
 
 	/*
 	 * Apply hardware packet filter.
@@ -1289,6 +1299,12 @@ static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
 	if (queue != IEEE80211_TX_QUEUE_BEACON)
 		return;
 
+	/*
+	 * For Wi-Fi faily generated beacons between participating stations.
+	 * Set TBTT phase adaptive adjustment step to 8us (default 16us)
+	 */
+	rt73usb_register_write(rt2x00dev, TXRX_CSR10, 0x00001008);
+
 	rt73usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
 	if (!rt2x00_get_field32(reg, TXRX_CSR9_BEACON_GEN)) {
 		rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 1);
@@ -1850,6 +1866,45 @@ static void rt73usb_reset_tsf(struct ieee80211_hw *hw)
 	rt73usb_register_write(rt2x00dev, TXRX_CSR13, 0);
 }
 
+int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
+			  struct ieee80211_tx_control *control)
+{
+	struct rt2x00_dev *rt2x00dev = hw->priv;
+	struct data_ring *ring =
+	    rt2x00lib_get_ring(rt2x00dev, IEEE80211_TX_QUEUE_BEACON);
+	int timeout;
+
+	/*
+	 * Just in case the ieee80211 doesn't set this,
+	 * but we need this queue set for the descriptor
+	 * initialization.
+	 */
+	control->queue = IEEE80211_TX_QUEUE_BEACON;
+
+	/*
+	 * First we create the beacon.
+	 */
+	skb_push(skb, ring->desc_size);
+	rt2x00lib_write_tx_desc(rt2x00dev, ring->entry,
+				(struct data_desc *)skb->data,
+				(struct ieee80211_hdr *)(skb->data +
+							 ring->desc_size),
+				skb->len - ring->desc_size, control);
+
+	/*
+	 * Write entire beacon with descriptor to register,
+	 * and kick the beacon generator.
+	 */
+	timeout = REGISTER_TIMEOUT * (skb->len / sizeof(u32));
+	rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE,
+				 USB_VENDOR_REQUEST_OUT,
+				 HW_BEACON_BASE0, 0x0000,
+				 skb->data, skb->len, timeout);
+	rt73usb_kick_tx_queue(rt2x00dev, IEEE80211_TX_QUEUE_BEACON);
+
+	return 0;
+}
+
 static const struct ieee80211_ops rt73usb_mac80211_ops = {
 	.tx			= rt2x00mac_tx,
 	.add_interface		= rt2x00mac_add_interface,
@@ -1868,7 +1923,7 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
 	.get_tsf		= rt73usb_get_tsf,
 #endif
 	.reset_tsf		= rt73usb_reset_tsf,
-	.beacon_update		= rt2x00usb_beacon_update,
+	.beacon_update		= rt73usb_beacon_update,
 };
 
 static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
-- 
1.5.3

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

* [PATCH 6/24] rt2x00: Recalculate link quality
       [not found] <200709161403.11332.IvDoorn@gmail.com>
                   ` (4 preceding siblings ...)
  2007-09-16 12:18 ` [PATCH 5/24] rt2x00: Fix rt61pci and rt73usb beacon handling Ivo van Doorn
@ 2007-09-16 12:18 ` Ivo van Doorn
  2007-09-16 12:18 ` [PATCH 7/24] rt2x00: Cleanup entry->flags Ivo van Doorn
                   ` (17 subsequent siblings)
  23 siblings, 0 replies; 24+ messages in thread
From: Ivo van Doorn @ 2007-09-16 12:18 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, rt2400-devel

Split link quality calculation up into 2 parts:
 - calculate once per second the TX and RX success percentage
 - calculate per frame the total quality based on the TX and RX
   success percentage and the RSSI of the current frame.

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2x00.h    |   14 +++++++
 drivers/net/wireless/rt2x00/rt2x00dev.c |   65 +++++++++++++++----------------
 2 files changed, 45 insertions(+), 34 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index a7527cd..1f5b3cb 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -231,8 +231,10 @@ struct link {
 	 *
 	 * This value should then be checked to not be greated then 100.
 	 */
+	int rx_percentage;
 	int rx_success;
 	int rx_failed;
+	int tx_percentage;
 	int tx_success;
 	int tx_failed;
 #define WEIGHT_RSSI	20
@@ -246,6 +248,18 @@ struct link {
 };
 
 /*
+ * Clear all counters inside the link structure.
+ * This can be easiest achieved by memsetting everything
+ * except for the work structure at the end.
+ */
+static inline void rt2x00_clear_link(struct link *link)
+{
+	memset(link, 0x00, sizeof(*link) - sizeof(link->work));
+	link->rx_percentage = 50;
+	link->tx_percentage = 50;
+}
+
+/*
  * Update the rssi using the walking average approach.
  */
 static inline void rt2x00_update_link_rssi(struct link *link, int rssi)
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index f2adaf5..09c31e3 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -69,14 +69,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_get_ring);
  */
 static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev)
 {
-	rt2x00dev->link.count = 0;
-	rt2x00dev->link.avg_rssi = 0;
-	rt2x00dev->link.vgc_level = 0;
-	rt2x00dev->link.false_cca = 0;
-	rt2x00dev->link.rx_success = 0;
-	rt2x00dev->link.rx_failed = 0;
-	rt2x00dev->link.tx_success = 0;
-	rt2x00dev->link.tx_failed = 0;
+	rt2x00_clear_link(&rt2x00dev->link);
 
 	/*
 	 * Reset the link tuner.
@@ -184,13 +177,32 @@ void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, int enable)
 		rt2x00lib_start_link_tuner(rt2x00dev);
 }
 
-static int rt2x00lib_calculate_link_signal(struct rt2x00_dev *rt2x00dev)
+static void rt2x00lib_precalculate_link_signal(struct link *link)
+{
+	if (link->rx_failed || link->rx_success)
+		link->rx_percentage =
+		    (link->rx_success * 100) /
+		    (link->rx_failed + link->rx_success);
+	else
+		link->rx_percentage = 50;
+
+	if (link->tx_failed || link->tx_success)
+		link->tx_percentage =
+		    (link->tx_success * 100) /
+		    (link->tx_failed + link->tx_success);
+	else
+		link->tx_percentage = 50;
+
+	link->rx_success = 0;
+	link->rx_failed = 0;
+	link->tx_success = 0;
+	link->tx_failed = 0;
+}
+
+static int rt2x00lib_calculate_link_signal(struct rt2x00_dev *rt2x00dev,
+					   int rssi)
 {
-	struct link *link = &rt2x00dev->link;
 	int rssi_percentage = 0;
-	int rx_percentage = 0;
-	int tx_percentage = 0;
-	int rssi = rt2x00_get_link_rssi(link);
 	int signal;
 
 	/*
@@ -205,22 +217,14 @@ static int rt2x00lib_calculate_link_signal(struct rt2x00_dev *rt2x00dev)
 	 */
 	if (rt2x00dev->rssi_offset)
 		rssi_percentage = (rssi * 100) / rt2x00dev->rssi_offset;
-	if (link->rx_failed || link->rx_success)
-		rx_percentage =
-		    (link->rx_success * 100) /
-		    (link->rx_failed + link->rx_success);
-	if (link->tx_failed || link->tx_success)
-		tx_percentage =
-		    (link->tx_success * 100) /
-		    (link->tx_failed + link->tx_success);
 
 	/*
 	 * Add the individual percentages and use the WEIGHT
 	 * defines to calculate the current link signal.
 	 */
 	signal = ((WEIGHT_RSSI * rssi_percentage) +
-		  (WEIGHT_TX * tx_percentage) +
-		  (WEIGHT_RX * rx_percentage)) / 100;
+		  (WEIGHT_TX * rt2x00dev->link.tx_percentage) +
+		  (WEIGHT_RX * rt2x00dev->link.rx_percentage)) / 100;
 
 	return (signal > 100) ? 100 : signal;
 }
@@ -231,22 +235,15 @@ static void rt2x00lib_link_tuner(struct work_struct *work)
 	    container_of(work, struct rt2x00_dev, link.work.work);
 
 	/*
-	 * Reset statistics.
-	 * This will cause the signal value to be
-	 * based on the statistics of the last second.
-	 */
-	rt2x00dev->link.rx_success = 0;
-	rt2x00dev->link.rx_failed = 0;
-	rt2x00dev->link.tx_success = 0;
-	rt2x00dev->link.tx_failed = 0;
-
-	/*
 	 * Update statistics.
 	 */
 	rt2x00dev->ops->lib->link_stats(rt2x00dev);
+
 	rt2x00dev->low_level_stats.dot11FCSErrorCount +=
 	    rt2x00dev->link.rx_failed;
 
+	rt2x00lib_precalculate_link_signal(&rt2x00dev->link);
+
 	/*
 	 * Only perform the link tuning when Link tuning
 	 * has been enabled (This could have been disabled from the EEPROM).
@@ -377,7 +374,7 @@ void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb,
 	rt2x00_update_link_rssi(&rt2x00dev->link, rssi);
 	rt2x00dev->link.rx_success++;
 	rx_status->rate = val;
-	rx_status->signal = rt2x00lib_calculate_link_signal(rt2x00dev);
+	rx_status->signal = rt2x00lib_calculate_link_signal(rt2x00dev, rssi);
 	rx_status->ssi = rssi;
 
 	/*
-- 
1.5.3

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

* [PATCH 7/24] rt2x00: Cleanup entry->flags
       [not found] <200709161403.11332.IvDoorn@gmail.com>
                   ` (5 preceding siblings ...)
  2007-09-16 12:18 ` [PATCH 6/24] rt2x00: Recalculate link quality Ivo van Doorn
@ 2007-09-16 12:18 ` Ivo van Doorn
  2007-09-16 12:18 ` [PATCH 8/24] rt2x00: Reduce LNA flags Ivo van Doorn
                   ` (16 subsequent siblings)
  23 siblings, 0 replies; 24+ messages in thread
From: Ivo van Doorn @ 2007-09-16 12:18 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, rt2400-devel

By moving all TXD flags from entry->flags to the
desc->flags we can remove entry argument for
write_tx_desc and replace it with the ring argument.

This will remove unrequired access to the entry array
inside the dataring.

Remove entry argument from write_tx_desc, by adding
rt2x00_get_ring from write_tx_ring itself we can better
check for NULL and we can use a fallback ring to get
the cw_min/cw_max values from.

Also remove the ring usage from beacon_update in
rt61pci and rt73usb. Since they no longer use the
beacon ring DMA, they shouldn't use the ring structure
either.

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2400pci.c  |    7 ++---
 drivers/net/wireless/rt2x00/rt2500pci.c  |   15 +++++------
 drivers/net/wireless/rt2x00/rt2500usb.c  |   16 +++++-------
 drivers/net/wireless/rt2x00/rt2x00.h     |    3 +-
 drivers/net/wireless/rt2x00/rt2x00dev.c  |   37 +++++++++++++++++++++--------
 drivers/net/wireless/rt2x00/rt2x00pci.c  |    4 +-
 drivers/net/wireless/rt2x00/rt2x00ring.h |   23 +++++++++++++-----
 drivers/net/wireless/rt2x00/rt2x00usb.c  |    5 +--
 drivers/net/wireless/rt2x00/rt61pci.c    |   31 ++++++++++--------------
 drivers/net/wireless/rt2x00/rt73usb.c    |   28 +++++++++-------------
 10 files changed, 90 insertions(+), 79 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index cdafbee..22834a5 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1091,7 +1091,6 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev,
  * TX descriptor initialization
  */
 static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
-				    struct data_entry *entry,
 				    struct data_desc *txd,
 				    struct data_entry_desc *desc,
 				    struct ieee80211_hdr *ieee80211hdr,
@@ -1145,13 +1144,13 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
 	rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1);
 	rt2x00_set_field32(&word, TXD_W0_VALID, 1);
 	rt2x00_set_field32(&word, TXD_W0_MORE_FRAG,
-			   test_bit(ENTRY_TXD_MORE_FRAG, &entry->flags));
+			   test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags));
 	rt2x00_set_field32(&word, TXD_W0_ACK,
 			   !(control->flags & IEEE80211_TXCTL_NO_ACK));
 	rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
-			   test_bit(ENTRY_TXD_REQ_TIMESTAMP, &entry->flags));
+			   test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags));
 	rt2x00_set_field32(&word, TXD_W0_RTS,
-			   test_bit(ENTRY_TXD_RTS_FRAME, &entry->flags));
+			   test_bit(ENTRY_TXD_RTS_FRAME, &desc->flags));
 	rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs);
 	rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
 			   !!(control->flags &
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 03c85a2..be82f2d 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1236,7 +1236,6 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev,
  * TX descriptor initialization
  */
 static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
-				    struct data_entry *entry,
 				    struct data_desc *txd,
 				    struct data_entry_desc *desc,
 				    struct ieee80211_hdr *ieee80211hdr,
@@ -1250,9 +1249,9 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
 	 */
 	rt2x00_desc_read(txd, 2, &word);
 	rt2x00_set_field32(&word, TXD_W2_IV_OFFSET, IEEE80211_HEADER);
-	rt2x00_set_field32(&word, TXD_W2_AIFS, entry->ring->tx_params.aifs);
-	rt2x00_set_field32(&word, TXD_W2_CWMIN, entry->ring->tx_params.cw_min);
-	rt2x00_set_field32(&word, TXD_W2_CWMAX, entry->ring->tx_params.cw_max);
+	rt2x00_set_field32(&word, TXD_W2_AIFS, desc->aifs);
+	rt2x00_set_field32(&word, TXD_W2_CWMIN, desc->cw_min);
+	rt2x00_set_field32(&word, TXD_W2_CWMAX, desc->cw_max);
 	rt2x00_desc_write(txd, 2, word);
 
 	rt2x00_desc_read(txd, 3, &word);
@@ -1264,20 +1263,20 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
 
 	rt2x00_desc_read(txd, 10, &word);
 	rt2x00_set_field32(&word, TXD_W10_RTS,
-			   test_bit(ENTRY_TXD_RTS_FRAME, &entry->flags));
+			   test_bit(ENTRY_TXD_RTS_FRAME, &desc->flags));
 	rt2x00_desc_write(txd, 10, word);
 
 	rt2x00_desc_read(txd, 0, &word);
 	rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1);
 	rt2x00_set_field32(&word, TXD_W0_VALID, 1);
 	rt2x00_set_field32(&word, TXD_W0_MORE_FRAG,
-			   test_bit(ENTRY_TXD_MORE_FRAG, &entry->flags));
+			   test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags));
 	rt2x00_set_field32(&word, TXD_W0_ACK,
 			   !(control->flags & IEEE80211_TXCTL_NO_ACK));
 	rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
-			   test_bit(ENTRY_TXD_REQ_TIMESTAMP, &entry->flags));
+			   test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags));
 	rt2x00_set_field32(&word, TXD_W0_OFDM,
-			   test_bit(ENTRY_TXD_OFDM_RATE, &entry->flags));
+			   test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags));
 	rt2x00_set_field32(&word, TXD_W0_CIPHER_OWNER, 1);
 	rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs);
 	rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 06219ce..c4f12cd 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1034,7 +1034,6 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev,
  * TX descriptor initialization
  */
 static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
-				    struct data_entry *entry,
 				    struct data_desc *txd,
 				    struct data_entry_desc *desc,
 				    struct ieee80211_hdr *ieee80211hdr,
@@ -1048,9 +1047,9 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
 	 */
 	rt2x00_desc_read(txd, 1, &word);
 	rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER);
-	rt2x00_set_field32(&word, TXD_W1_AIFS, entry->ring->tx_params.aifs);
-	rt2x00_set_field32(&word, TXD_W1_CWMIN, entry->ring->tx_params.cw_min);
-	rt2x00_set_field32(&word, TXD_W1_CWMAX, entry->ring->tx_params.cw_max);
+	rt2x00_set_field32(&word, TXD_W1_AIFS, desc->aifs);
+	rt2x00_set_field32(&word, TXD_W1_CWMIN, desc->cw_min);
+	rt2x00_set_field32(&word, TXD_W1_CWMAX, desc->cw_max);
 	rt2x00_desc_write(txd, 1, word);
 
 	rt2x00_desc_read(txd, 2, &word);
@@ -1063,13 +1062,13 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
 	rt2x00_desc_read(txd, 0, &word);
 	rt2x00_set_field32(&word, TXD_W0_RETRY_LIMIT, control->retry_limit);
 	rt2x00_set_field32(&word, TXD_W0_MORE_FRAG,
-			   test_bit(ENTRY_TXD_MORE_FRAG, &entry->flags));
+			   test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags));
 	rt2x00_set_field32(&word, TXD_W0_ACK,
 			   !(control->flags & IEEE80211_TXCTL_NO_ACK));
 	rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
-			   test_bit(ENTRY_TXD_REQ_TIMESTAMP, &entry->flags));
+			   test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags));
 	rt2x00_set_field32(&word, TXD_W0_OFDM,
-			   test_bit(ENTRY_TXD_OFDM_RATE, &entry->flags));
+			   test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags));
 	rt2x00_set_field32(&word, TXD_W0_NEW_SEQ,
 			   !!(control->flags & IEEE80211_TXCTL_FIRST_FRAGMENT));
 	rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs);
@@ -1620,8 +1619,7 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw,
 	 * First we create the beacon.
 	 */
 	skb_push(skb, ring->desc_size);
-	rt2x00lib_write_tx_desc(rt2x00dev, beacon,
-				(struct data_desc *)skb->data,
+	rt2x00lib_write_tx_desc(rt2x00dev, (struct data_desc *)skb->data,
 				(struct ieee80211_hdr *)(skb->data +
 							 ring->desc_size),
 				skb->len - ring->desc_size, control);
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 1f5b3cb..40dd52b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -401,7 +401,6 @@ struct rt2x00lib_ops {
 	 * TX control handlers
 	 */
 	void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev,
-			       struct data_entry *entry,
 			       struct data_desc *txd,
 			       struct data_entry_desc *desc,
 			       struct ieee80211_hdr *ieee80211hdr,
@@ -763,7 +762,7 @@ void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb,
  * TX descriptor initializer
  */
 void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
-			     struct data_entry *entry, struct data_desc *txd,
+			     struct data_desc *txd,
 			     struct ieee80211_hdr *ieee80211hdr,
 			     unsigned int length,
 			     struct ieee80211_tx_control *control);
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 09c31e3..fed2cce 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -388,13 +388,13 @@ EXPORT_SYMBOL_GPL(rt2x00lib_rxdone);
  * TX descriptor initializer
  */
 void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
-			     struct data_entry *entry,
 			     struct data_desc *txd,
 			     struct ieee80211_hdr *ieee80211hdr,
 			     unsigned int length,
 			     struct ieee80211_tx_control *control)
 {
 	struct data_entry_desc desc;
+	struct data_ring *ring;
 	int tx_rate;
 	int bitrate;
 	int duration;
@@ -403,6 +403,23 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
 	u16 seq_ctrl;
 
 	/*
+	 * Make sure the descriptor is properly cleared.
+	 */
+	memset(&desc, 0x00, sizeof(desc));
+
+	/*
+	 * Get ring pointer, if we fail to obtain the
+	 * correct ring, then use the first TX ring.
+	 */
+	ring = rt2x00lib_get_ring(rt2x00dev, control->queue);
+	if (!ring)
+		ring = rt2x00lib_get_ring(rt2x00dev, IEEE80211_TX_QUEUE_DATA0);
+
+	desc.cw_min = ring->tx_params.cw_min;
+	desc.cw_max = ring->tx_params.cw_max;
+	desc.aifs = ring->tx_params.aifs;
+
+	/*
 	 * Identify queue
 	 */
 	if (control->queue < rt2x00dev->hw->queues)
@@ -422,9 +439,9 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
 	 * Check if this is a RTS/CTS frame
 	 */
 	if (is_rts_frame(frame_control) || is_cts_frame(frame_control)) {
-		__set_bit(ENTRY_TXD_BURST, &entry->flags);
+		__set_bit(ENTRY_TXD_BURST, &desc.flags);
 		if (is_rts_frame(frame_control))
-			__set_bit(ENTRY_TXD_RTS_FRAME, &entry->flags);
+			__set_bit(ENTRY_TXD_RTS_FRAME, &desc.flags);
 		if (control->rts_cts_rate)
 			tx_rate = control->rts_cts_rate;
 	}
@@ -433,14 +450,14 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
 	 * Check for OFDM
 	 */
 	if (DEVICE_GET_RATE_FIELD(tx_rate, RATEMASK) & DEV_OFDM_RATEMASK)
-		__set_bit(ENTRY_TXD_OFDM_RATE, &entry->flags);
+		__set_bit(ENTRY_TXD_OFDM_RATE, &desc.flags);
 
 	/*
 	 * Check if more fragments are pending
 	 */
 	if (ieee80211_get_morefrag(ieee80211hdr)) {
-		__set_bit(ENTRY_TXD_BURST, &entry->flags);
-		__set_bit(ENTRY_TXD_MORE_FRAG, &entry->flags);
+		__set_bit(ENTRY_TXD_BURST, &desc.flags);
+		__set_bit(ENTRY_TXD_MORE_FRAG, &desc.flags);
 	}
 
 	/*
@@ -449,7 +466,7 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
 	 */
 	if (control->queue == IEEE80211_TX_QUEUE_BEACON ||
 	    is_probe_resp(frame_control))
-		__set_bit(ENTRY_TXD_REQ_TIMESTAMP, &entry->flags);
+		__set_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc.flags);
 
 	/*
 	 * Determine with what IFS priority this frame should be send.
@@ -457,7 +474,7 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
 	 * or this fragment came after RTS/CTS.
 	 */
 	if ((seq_ctrl & IEEE80211_SCTL_FRAG) > 0 ||
-	    test_bit(ENTRY_TXD_RTS_FRAME, &entry->flags))
+	    test_bit(ENTRY_TXD_RTS_FRAME, &desc.flags))
 		desc.ifs = IFS_SIFS;
 	else
 		desc.ifs = IFS_BACKOFF;
@@ -469,7 +486,7 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
 	desc.signal = DEVICE_GET_RATE_FIELD(tx_rate, PLCP);
 	desc.service = 0x04;
 
-	if (test_bit(ENTRY_TXD_OFDM_RATE, &entry->flags)) {
+	if (test_bit(ENTRY_TXD_OFDM_RATE, &desc.flags)) {
 		desc.length_high = ((length + FCS_LEN) >> 6) & 0x3f;
 		desc.length_low = ((length + FCS_LEN) & 0x3f);
 	} else {
@@ -502,7 +519,7 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
 			desc.signal |= 0x08;
 	}
 
-	rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, entry, txd, &desc,
+	rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, txd, &desc,
 					   ieee80211hdr, length, control);
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_write_tx_desc);
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 66fce58..f61cc7f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -58,7 +58,7 @@ int rt2x00pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
 	 * Update the beacon entry.
 	 */
 	memcpy(entry->data_addr, skb->data, skb->len);
-	rt2x00lib_write_tx_desc(rt2x00dev, entry, entry->priv,
+	rt2x00lib_write_tx_desc(rt2x00dev, entry->priv,
 				(struct ieee80211_hdr *)skb->data,
 				skb->len, control);
 
@@ -103,7 +103,7 @@ int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev,
 	entry->skb = skb;
 	memcpy(&entry->tx_status.control, control, sizeof(*control));
 	memcpy(entry->data_addr, skb->data, skb->len);
-	rt2x00lib_write_tx_desc(rt2x00dev, entry, txd, ieee80211hdr,
+	rt2x00lib_write_tx_desc(rt2x00dev, txd, ieee80211hdr,
 				skb->len, control);
 
 	rt2x00_ring_index_inc(ring);
diff --git a/drivers/net/wireless/rt2x00/rt2x00ring.h b/drivers/net/wireless/rt2x00/rt2x00ring.h
index 143ad6d..78e128a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00ring.h
+++ b/drivers/net/wireless/rt2x00/rt2x00ring.h
@@ -46,6 +46,16 @@ struct data_desc {
  * descriptor for sending a TX frame.
  */
 struct data_entry_desc {
+	unsigned long flags;
+#define ENTRY_TXDONE		1
+#define ENTRY_TXD_RTS_FRAME	2
+#define ENTRY_TXD_OFDM_RATE	3
+#define ENTRY_TXD_MORE_FRAG	4
+#define ENTRY_TXD_REQ_TIMESTAMP	5
+#define ENTRY_TXD_BURST		6
+
+	int queue;
+
 	/*
 	 * PLCP values.
 	 */
@@ -54,8 +64,13 @@ struct data_entry_desc {
 	u16 signal;
 	u16 service;
 
-	int queue;
+	/*
+	 * Timing information
+	 */
+	int aifs;
 	int ifs;
+	int cw_min;
+	int cw_max;
 };
 
 /*
@@ -71,12 +86,6 @@ struct data_entry {
 	 */
 	unsigned long flags;
 #define ENTRY_OWNER_NIC		1
-#define ENTRY_TXDONE		2
-#define ENTRY_TXD_RTS_FRAME	3
-#define ENTRY_TXD_OFDM_RATE	4
-#define ENTRY_TXD_MORE_FRAG	5
-#define ENTRY_TXD_REQ_TIMESTAMP	6
-#define ENTRY_TXD_BURST		7
 
 	/*
 	 * Ring we belong to.
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 246ba93..ede3766 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -183,9 +183,8 @@ int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev,
 	skb_push(skb, rt2x00dev->hw->extra_tx_headroom);
 	memset(skb->data, 0x00, rt2x00dev->hw->extra_tx_headroom);
 
-	rt2x00lib_write_tx_desc(rt2x00dev, entry,
-				(struct data_desc *)skb->data, ieee80211hdr,
-				length, control);
+	rt2x00lib_write_tx_desc(rt2x00dev, (struct data_desc *)skb->data,
+				ieee80211hdr, length, control);
 	memcpy(&entry->tx_status.control, control, sizeof(*control));
 	entry->skb = skb;
 
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index fe9edb9..b94f005 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1089,7 +1089,6 @@ static int rt61pci_init_rings(struct rt2x00_dev *rt2x00dev)
 	rt61pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA2);
 	rt61pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA3);
 	rt61pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_DATA4);
-	rt61pci_init_txring(rt2x00dev, IEEE80211_TX_QUEUE_BEACON);
 
 	/*
 	 * Initialize registers.
@@ -1489,7 +1488,6 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev,
  * TX descriptor initialization
  */
 static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
-				  struct data_entry *entry,
 				  struct data_desc *txd,
 				  struct data_entry_desc *desc,
 				  struct ieee80211_hdr *ieee80211hdr,
@@ -1503,9 +1501,9 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
 	 */
 	rt2x00_desc_read(txd, 1, &word);
 	rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, desc->queue);
-	rt2x00_set_field32(&word, TXD_W1_AIFSN, entry->ring->tx_params.aifs);
-	rt2x00_set_field32(&word, TXD_W1_CWMIN, entry->ring->tx_params.cw_min);
-	rt2x00_set_field32(&word, TXD_W1_CWMAX, entry->ring->tx_params.cw_max);
+	rt2x00_set_field32(&word, TXD_W1_AIFSN, desc->aifs);
+	rt2x00_set_field32(&word, TXD_W1_CWMIN, desc->cw_min);
+	rt2x00_set_field32(&word, TXD_W1_CWMAX, desc->cw_max);
 	rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER);
 	rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1);
 	rt2x00_desc_write(txd, 1, word);
@@ -1531,13 +1529,13 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
 	rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 1);
 	rt2x00_set_field32(&word, TXD_W0_VALID, 1);
 	rt2x00_set_field32(&word, TXD_W0_MORE_FRAG,
-			   test_bit(ENTRY_TXD_MORE_FRAG, &entry->flags));
+			   test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags));
 	rt2x00_set_field32(&word, TXD_W0_ACK,
 			   !(control->flags & IEEE80211_TXCTL_NO_ACK));
 	rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
-			   test_bit(ENTRY_TXD_REQ_TIMESTAMP, &entry->flags));
+			   test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags));
 	rt2x00_set_field32(&word, TXD_W0_OFDM,
-			   test_bit(ENTRY_TXD_OFDM_RATE, &entry->flags));
+			   test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags));
 	rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs);
 	rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
 			   !!(control->flags &
@@ -1545,7 +1543,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
 	rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0);
 	rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, length);
 	rt2x00_set_field32(&word, TXD_W0_BURST,
-			   test_bit(ENTRY_TXD_BURST, &entry->flags));
+			   test_bit(ENTRY_TXD_BURST, &desc->flags));
 	rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE);
 	rt2x00_desc_write(txd, 0, word);
 }
@@ -2255,8 +2253,6 @@ int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
 			  struct ieee80211_tx_control *control)
 {
 	struct rt2x00_dev *rt2x00dev = hw->priv;
-	struct data_ring *ring =
-	    rt2x00lib_get_ring(rt2x00dev, IEEE80211_TX_QUEUE_BEACON);
 
 	/*
 	 * Just in case the ieee80211 doesn't set this,
@@ -2269,8 +2265,8 @@ int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
 	 * We need to append the descriptor in front of the
 	 * beacon frame.
 	 */
-	if (skb_headroom(skb) < ring->desc_size) {
-		if (pskb_expand_head(skb, ring->desc_size, 0, GFP_ATOMIC)) {
+	if (skb_headroom(skb) < TXD_DESC_SIZE) {
+		if (pskb_expand_head(skb, TXD_DESC_SIZE, 0, GFP_ATOMIC)) {
 			dev_kfree_skb(skb);
 			return -ENOMEM;
 		}
@@ -2279,12 +2275,11 @@ int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
 	/*
 	 * First we create the beacon.
 	 */
-	skb_push(skb, ring->desc_size);
-	rt2x00lib_write_tx_desc(rt2x00dev, ring->entry,
-				(struct data_desc *)skb->data,
+	skb_push(skb, TXD_DESC_SIZE);
+	rt2x00lib_write_tx_desc(rt2x00dev, (struct data_desc *)skb->data,
 				(struct ieee80211_hdr *)(skb->data +
-							 ring->desc_size),
-				skb->len - ring->desc_size, control);
+							 TXD_DESC_SIZE),
+				skb->len - TXD_DESC_SIZE, control);
 
 	/*
 	 * Write entire beacon with descriptor to register,
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 78c15f4..feb211d 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1230,7 +1230,6 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev,
  * TX descriptor initialization
  */
 static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
-				  struct data_entry *entry,
 				  struct data_desc *txd,
 				  struct data_entry_desc *desc,
 				  struct ieee80211_hdr *ieee80211hdr,
@@ -1244,9 +1243,9 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
 	 */
 	rt2x00_desc_read(txd, 1, &word);
 	rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, desc->queue);
-	rt2x00_set_field32(&word, TXD_W1_AIFSN, entry->ring->tx_params.aifs);
-	rt2x00_set_field32(&word, TXD_W1_CWMIN, entry->ring->tx_params.cw_min);
-	rt2x00_set_field32(&word, TXD_W1_CWMAX, entry->ring->tx_params.cw_max);
+	rt2x00_set_field32(&word, TXD_W1_AIFSN, desc->aifs);
+	rt2x00_set_field32(&word, TXD_W1_CWMIN, desc->cw_min);
+	rt2x00_set_field32(&word, TXD_W1_CWMAX, desc->cw_max);
 	rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER);
 	rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1);
 	rt2x00_desc_write(txd, 1, word);
@@ -1266,16 +1265,16 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
 
 	rt2x00_desc_read(txd, 0, &word);
 	rt2x00_set_field32(&word, TXD_W0_BURST,
-			   test_bit(ENTRY_TXD_BURST, &entry->flags));
+			   test_bit(ENTRY_TXD_BURST, &desc->flags));
 	rt2x00_set_field32(&word, TXD_W0_VALID, 1);
 	rt2x00_set_field32(&word, TXD_W0_MORE_FRAG,
-			   test_bit(ENTRY_TXD_MORE_FRAG, &entry->flags));
+			   test_bit(ENTRY_TXD_MORE_FRAG, &desc->flags));
 	rt2x00_set_field32(&word, TXD_W0_ACK,
 			   !(control->flags & IEEE80211_TXCTL_NO_ACK));
 	rt2x00_set_field32(&word, TXD_W0_TIMESTAMP,
-			   test_bit(ENTRY_TXD_REQ_TIMESTAMP, &entry->flags));
+			   test_bit(ENTRY_TXD_REQ_TIMESTAMP, &desc->flags));
 	rt2x00_set_field32(&word, TXD_W0_OFDM,
-			   test_bit(ENTRY_TXD_OFDM_RATE, &entry->flags));
+			   test_bit(ENTRY_TXD_OFDM_RATE, &desc->flags));
 	rt2x00_set_field32(&word, TXD_W0_IFS, desc->ifs);
 	rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
 			   !!(control->flags &
@@ -1283,7 +1282,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
 	rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0);
 	rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, length);
 	rt2x00_set_field32(&word, TXD_W0_BURST2,
-			   test_bit(ENTRY_TXD_BURST, &entry->flags));
+			   test_bit(ENTRY_TXD_BURST, &desc->flags));
 	rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE);
 	rt2x00_desc_write(txd, 0, word);
 }
@@ -1870,8 +1869,6 @@ int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
 			  struct ieee80211_tx_control *control)
 {
 	struct rt2x00_dev *rt2x00dev = hw->priv;
-	struct data_ring *ring =
-	    rt2x00lib_get_ring(rt2x00dev, IEEE80211_TX_QUEUE_BEACON);
 	int timeout;
 
 	/*
@@ -1884,12 +1881,11 @@ int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
 	/*
 	 * First we create the beacon.
 	 */
-	skb_push(skb, ring->desc_size);
-	rt2x00lib_write_tx_desc(rt2x00dev, ring->entry,
-				(struct data_desc *)skb->data,
+	skb_push(skb, TXD_DESC_SIZE);
+	rt2x00lib_write_tx_desc(rt2x00dev, (struct data_desc *)skb->data,
 				(struct ieee80211_hdr *)(skb->data +
-							 ring->desc_size),
-				skb->len - ring->desc_size, control);
+							 TXD_DESC_SIZE),
+				skb->len - TXD_DESC_SIZE, control);
 
 	/*
 	 * Write entire beacon with descriptor to register,
-- 
1.5.3

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

* [PATCH 8/24] rt2x00: Reduce LNA flags
       [not found] <200709161403.11332.IvDoorn@gmail.com>
                   ` (6 preceding siblings ...)
  2007-09-16 12:18 ` [PATCH 7/24] rt2x00: Cleanup entry->flags Ivo van Doorn
@ 2007-09-16 12:18 ` Ivo van Doorn
  2007-09-16 12:18 ` [PATCH 9/24] rt2x00: Rework RT61 and RT73 Antenna handling Ivo van Doorn
                   ` (15 subsequent siblings)
  23 siblings, 0 replies; 24+ messages in thread
From: Ivo van Doorn @ 2007-09-16 12:18 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, rt2400-devel

Because rt73usb has LNA in a single variable
and rt61pci has LNA for A and BG modes we currently
had 3 flags for LNA.

Reduce this by setting LNA_A and LNA_BG if rt73usb has
LNA enabled.

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

diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 40dd52b..02a5adf 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -520,7 +520,7 @@ struct rt2x00_dev {
 #define DEVICE_SUPPORT_HW_BUTTON	12
 #define CONFIG_FRAME_TYPE		13
 #define CONFIG_RF_SEQUENCE		14
-#define CONFIG_EXTERNAL_LNA		15
+/* Hole: Add new Flag here */
 #define CONFIG_EXTERNAL_LNA_A		16
 #define CONFIG_EXTERNAL_LNA_BG		17
 #define CONFIG_DOUBLE_ANTENNA		18
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index feb211d..703e4e1 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -519,7 +519,7 @@ static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev,
 	rt73usb_register_read(rt2x00dev, PHY_CSR0, &reg);
 
 	if (rt2x00dev->curr_hwmode == HWMODE_A) {
-		if (test_bit(CONFIG_EXTERNAL_LNA, &rt2x00dev->flags)) {
+		if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) {
 			rt73usb_bbp_write(rt2x00dev, 96, 0x78);
 			rt73usb_bbp_write(rt2x00dev, 104, 0x48);
 			rt73usb_bbp_write(rt2x00dev, 75, 0x80);
@@ -539,7 +539,7 @@ static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev,
 		rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_BG, 0);
 		rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_A, 1);
 	} else {
-		if (test_bit(CONFIG_EXTERNAL_LNA, &rt2x00dev->flags)) {
+		if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) {
 			rt73usb_bbp_write(rt2x00dev, 96, 0x68);
 			rt73usb_bbp_write(rt2x00dev, 104, 0x3c);
 			rt73usb_bbp_write(rt2x00dev, 75, 0x80);
@@ -792,7 +792,7 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
 		low_bound = 0x28;
 		up_bound = 0x48;
 
-		if (test_bit(CONFIG_EXTERNAL_LNA, &rt2x00dev->flags)) {
+		if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) {
 			low_bound += 0x10;
 			up_bound += 0x10;
 		}
@@ -808,7 +808,7 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
 			up_bound = 0x1c;
 		}
 
-		if (test_bit(CONFIG_EXTERNAL_LNA, &rt2x00dev->flags)) {
+		if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) {
 			low_bound += 0x14;
 			up_bound += 0x10;
 		}
@@ -1336,7 +1336,7 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1)
 	}
 
 	if (rt2x00dev->rx_status.phymode == MODE_IEEE80211A) {
-		if (test_bit(CONFIG_EXTERNAL_LNA, &rt2x00dev->flags)) {
+		if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) {
 			if (lna == 3 || lna == 2)
 				offset += 10;
 		} else {
@@ -1349,7 +1349,7 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1)
 		rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_A, &eeprom);
 		offset -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_A_1);
 	} else {
-		if (test_bit(CONFIG_EXTERNAL_LNA, &rt2x00dev->flags))
+		if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags))
 			offset += 14;
 
 		rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom);
@@ -1544,8 +1544,10 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
 	 */
 	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
 
-	if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA))
-		__set_bit(CONFIG_EXTERNAL_LNA, &rt2x00dev->flags);
+	if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA)) {
+		__set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
+		__set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
+	}
 
 	/*
 	 * Store led settings, for correct led behaviour.
-- 
1.5.3

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

* [PATCH 9/24] rt2x00: Rework RT61 and RT73 Antenna handling
       [not found] <200709161403.11332.IvDoorn@gmail.com>
                   ` (7 preceding siblings ...)
  2007-09-16 12:18 ` [PATCH 8/24] rt2x00: Reduce LNA flags Ivo van Doorn
@ 2007-09-16 12:18 ` Ivo van Doorn
  2007-09-16 12:18 ` [PATCH 10/24] rt2x00: Rename DEVICE_SUPPORT_ATIM to REQUIRE_BEACON_RING Ivo van Doorn
                   ` (14 subsequent siblings)
  23 siblings, 0 replies; 24+ messages in thread
From: Ivo van Doorn @ 2007-09-16 12:18 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, rt2400-devel

Rework rt61 and rt73 antenna handling because in case
of rt73 it looked ugly, and in case of rt61 it looked worse
and didn't contain all code for rf2529 chips.

Split the code up over several functions, and make it
a bit more manageble.

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2400pci.c |   24 ++-
 drivers/net/wireless/rt2x00/rt2500pci.c |   23 ++-
 drivers/net/wireless/rt2x00/rt2500usb.c |   23 ++-
 drivers/net/wireless/rt2x00/rt2x00reg.h |    3 +-
 drivers/net/wireless/rt2x00/rt61pci.c   |  321 ++++++++++++++++++++++---------
 drivers/net/wireless/rt2x00/rt61pci.h   |    8 +-
 drivers/net/wireless/rt2x00/rt73usb.c   |  224 ++++++++++++----------
 drivers/net/wireless/rt2x00/rt73usb.h   |    3 +-
 8 files changed, 417 insertions(+), 212 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 22834a5..5a7fc18 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -494,22 +494,34 @@ static void rt2400pci_config_antenna(struct rt2x00_dev *rt2x00dev,
 	/*
 	 * Configure the TX antenna.
 	 */
-	if (antenna_tx == ANTENNA_DIVERSITY)
+	switch (antenna_tx) {
+	case ANTENNA_SW_DIVERSITY:
+	case ANTENNA_HW_DIVERSITY:
 		rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 1);
-	else if (antenna_tx == ANTENNA_A)
+		break;
+	case ANTENNA_A:
 		rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 0);
-	else if (antenna_tx == ANTENNA_B)
+		break;
+	case ANTENNA_B:
 		rt2x00_set_field8(&r1, BBP_R1_TX_ANTENNA, 2);
+		break;
+	}
 
 	/*
 	 * Configure the RX antenna.
 	 */
-	if (antenna_rx == ANTENNA_DIVERSITY)
+	switch (antenna_rx) {
+	case ANTENNA_SW_DIVERSITY:
+	case ANTENNA_HW_DIVERSITY:
 		rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
-	else if (antenna_rx == ANTENNA_A)
+		break;
+	case ANTENNA_A:
 		rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 0);
-	else if (antenna_rx == ANTENNA_B)
+		break;
+	case ANTENNA_B:
 		rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
+		break;
+	}
 
 	rt2400pci_bbp_write(rt2x00dev, 4, r4);
 	rt2400pci_bbp_write(rt2x00dev, 1, r1);
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index be82f2d..d24ea61 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -532,29 +532,40 @@ static void rt2500pci_config_antenna(struct rt2x00_dev *rt2x00dev,
 	/*
 	 * Configure the TX antenna.
 	 */
-	if (antenna_tx == ANTENNA_DIVERSITY) {
+	switch (antenna_tx) {
+	case ANTENNA_SW_DIVERSITY:
+	case ANTENNA_HW_DIVERSITY:
 		rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2);
 		rt2x00_set_field32(&reg, BBPCSR1_CCK, 2);
 		rt2x00_set_field32(&reg, BBPCSR1_OFDM, 2);
-	} else if (antenna_tx == ANTENNA_A) {
+		break;
+	case ANTENNA_A:
 		rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 0);
 		rt2x00_set_field32(&reg, BBPCSR1_CCK, 0);
 		rt2x00_set_field32(&reg, BBPCSR1_OFDM, 0);
-	} else if (antenna_tx == ANTENNA_B) {
+		break;
+	case ANTENNA_B:
 		rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2);
 		rt2x00_set_field32(&reg, BBPCSR1_CCK, 2);
 		rt2x00_set_field32(&reg, BBPCSR1_OFDM, 2);
+		break;
 	}
 
 	/*
 	 * Configure the RX antenna.
 	 */
-	if (antenna_rx == ANTENNA_DIVERSITY)
+	switch (antenna_rx) {
+	case ANTENNA_SW_DIVERSITY:
+	case ANTENNA_HW_DIVERSITY:
 		rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2);
-	else if (antenna_rx == ANTENNA_A)
+		break;
+	case ANTENNA_A:
 		rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 0);
-	else if (antenna_rx == ANTENNA_B)
+		break;
+	case ANTENNA_B:
 		rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2);
+		break;
+	}
 
 	/*
 	 * RT2525E and RT5222 need to flip TX I/Q
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index c4f12cd..f344c2a 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -494,29 +494,40 @@ static void rt2500usb_config_antenna(struct rt2x00_dev *rt2x00dev,
 	/*
 	 * Configure the TX antenna.
 	 */
-	if (antenna_tx == ANTENNA_DIVERSITY) {
+	switch (antenna_tx) {
+	case ANTENNA_SW_DIVERSITY:
+	case ANTENNA_HW_DIVERSITY:
 		rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 1);
 		rt2x00_set_field16(&csr5, PHY_CSR5_CCK, 1);
 		rt2x00_set_field16(&csr6, PHY_CSR6_OFDM, 1);
-	} else if (antenna_tx == ANTENNA_A) {
+		break;
+	case ANTENNA_A:
 		rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 0);
 		rt2x00_set_field16(&csr5, PHY_CSR5_CCK, 0);
 		rt2x00_set_field16(&csr6, PHY_CSR6_OFDM, 0);
-	} else if (antenna_tx == ANTENNA_B) {
+		break;
+	case ANTENNA_B:
 		rt2x00_set_field8(&r2, BBP_R2_TX_ANTENNA, 2);
 		rt2x00_set_field16(&csr5, PHY_CSR5_CCK, 2);
 		rt2x00_set_field16(&csr6, PHY_CSR6_OFDM, 2);
+		break;
 	}
 
 	/*
 	 * Configure the RX antenna.
 	 */
-	if (antenna_rx == ANTENNA_DIVERSITY)
+	switch (antenna_rx) {
+	case ANTENNA_SW_DIVERSITY:
+	case ANTENNA_HW_DIVERSITY:
 		rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 1);
-	else if (antenna_rx == ANTENNA_A)
+		break;
+	case ANTENNA_A:
 		rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 0);
-	else if (antenna_rx == ANTENNA_B)
+		break;
+	case ANTENNA_B:
 		rt2x00_set_field8(&r14, BBP_R14_RX_ANTENNA, 2);
+		break;
+	}
 
 	/*
 	 * RT2525E and RT5222 need to flip TX I/Q
diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h
index 690356f..5e7b63e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00reg.h
+++ b/drivers/net/wireless/rt2x00/rt2x00reg.h
@@ -41,9 +41,10 @@ enum TX_STATUS {
  * Antenna values
  */
 enum antenna {
-	ANTENNA_DIVERSITY = 0,
+	ANTENNA_SW_DIVERSITY = 0,
 	ANTENNA_A = 1,
 	ANTENNA_B = 2,
+	ANTENNA_HW_DIVERSITY = 3,
 };
 
 /*
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index b94f005..6199606 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -536,125 +536,262 @@ static void rt61pci_config_txpower(struct rt2x00_dev *rt2x00dev,
 	rt61pci_rf_write(rt2x00dev, 4, rf.rf4);
 }
 
-static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev,
-				   const int antenna_tx, const int antenna_rx)
+static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
+				      const int antenna_tx,
+				      const int antenna_rx)
 {
-	u32 reg;
 	u8 r3;
 	u8 r4;
 	u8 r77;
 
-	rt2x00pci_register_read(rt2x00dev, PHY_CSR0, &reg);
+	rt61pci_bbp_read(rt2x00dev, 3, &r3);
+	rt61pci_bbp_read(rt2x00dev, 4, &r4);
+	rt61pci_bbp_read(rt2x00dev, 77, &r77);
 
-	if (rt2x00dev->curr_hwmode == HWMODE_A) {
-		if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) {
-			rt61pci_bbp_write(rt2x00dev, 96, 0x78);
-			rt61pci_bbp_write(rt2x00dev, 104, 0x48);
-			rt61pci_bbp_write(rt2x00dev, 75, 0x80);
-			rt61pci_bbp_write(rt2x00dev, 86, 0x80);
-			rt61pci_bbp_write(rt2x00dev, 88, 0x80);
-		} else {
-			rt61pci_bbp_write(rt2x00dev, 96, 0x58);
-			rt61pci_bbp_write(rt2x00dev, 104, 0x38);
-			rt61pci_bbp_write(rt2x00dev, 75, 0xfe);
-			rt61pci_bbp_write(rt2x00dev, 86, 0xfe);
-			rt61pci_bbp_write(rt2x00dev, 88, 0xfe);
-		}
-		rt61pci_bbp_write(rt2x00dev, 35, 0x60);
-		rt61pci_bbp_write(rt2x00dev, 97, 0x58);
-		rt61pci_bbp_write(rt2x00dev, 98, 0x58);
+	rt2x00_set_field8(&r3, BBP_R3_SMART_MODE,
+			  !rt2x00_rf(&rt2x00dev->chip, RF5225));
 
-		rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_BG, 0);
-		rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_A, 1);
-	} else {
-		if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) {
-			rt61pci_bbp_write(rt2x00dev, 96, 0x68);
-			rt61pci_bbp_write(rt2x00dev, 104, 0x3c);
-			rt61pci_bbp_write(rt2x00dev, 75, 0x80);
-			rt61pci_bbp_write(rt2x00dev, 86, 0x80);
-			rt61pci_bbp_write(rt2x00dev, 88, 0x80);
-		} else {
-			rt61pci_bbp_write(rt2x00dev, 96, 0x48);
-			rt61pci_bbp_write(rt2x00dev, 104, 0x2c);
-			rt61pci_bbp_write(rt2x00dev, 75, 0xfe);
-			rt61pci_bbp_write(rt2x00dev, 86, 0xfe);
-			rt61pci_bbp_write(rt2x00dev, 88, 0xfe);
-		}
-		rt61pci_bbp_write(rt2x00dev, 35, 0x50);
-		rt61pci_bbp_write(rt2x00dev, 97, 0x48);
-		rt61pci_bbp_write(rt2x00dev, 98, 0x48);
+	switch (antenna_rx) {
+	case ANTENNA_SW_DIVERSITY:
+	case ANTENNA_HW_DIVERSITY:
+		rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
+		rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
+				  !!(rt2x00dev->curr_hwmode != HWMODE_A));
+		break;
+	case ANTENNA_A:
+		rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
+		rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
 
-		rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_BG, 1);
-		rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_A, 0);
+		if (rt2x00dev->curr_hwmode == HWMODE_A)
+			rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
+		else
+			rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
+		break;
+	case ANTENNA_B:
+		rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
+		rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
+
+		if (rt2x00dev->curr_hwmode == HWMODE_A)
+			rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
+		else
+			rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
+		break;
 	}
 
-	rt2x00pci_register_write(rt2x00dev, PHY_CSR0, reg);
+	rt61pci_bbp_write(rt2x00dev, 77, r77);
+	rt61pci_bbp_write(rt2x00dev, 3, r3);
+	rt61pci_bbp_write(rt2x00dev, 4, r4);
+}
+
+static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
+				      const int antenna_tx,
+				      const int antenna_rx)
+{
+	u8 r3;
+	u8 r4;
+	u8 r77;
 
 	rt61pci_bbp_read(rt2x00dev, 3, &r3);
 	rt61pci_bbp_read(rt2x00dev, 4, &r4);
 	rt61pci_bbp_read(rt2x00dev, 77, &r77);
 
-	if (rt2x00_rf(&rt2x00dev->chip, RF5225) ||
-	    rt2x00_rf(&rt2x00dev->chip, RF2527))
-		rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 0);
+	rt2x00_set_field8(&r3, BBP_R3_SMART_MODE,
+			  !rt2x00_rf(&rt2x00dev->chip, RF2527));
+	rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
+			  !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags));
 
-	if (rt2x00_rf(&rt2x00dev->chip, RF5225) ||
-	    rt2x00_rf(&rt2x00dev->chip, RF5325)) {
-		if (antenna_rx == ANTENNA_DIVERSITY) {
-			rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
-			if (rt2x00dev->curr_hwmode != HWMODE_A)
-				rt2x00_set_field8(&r4, BBP_R4_RX_BG_MODE, 1);
-		} else if (antenna_rx == ANTENNA_A) {
-			rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
-			if (rt2x00dev->curr_hwmode == HWMODE_A)
-				rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
-			else
-				rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
-			rt61pci_bbp_write(rt2x00dev, 77, r77);
-		} else if (antenna_rx == ANTENNA_B) {
-			rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
-			if (rt2x00dev->curr_hwmode == HWMODE_A)
-				rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
-			else
-				rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
+	switch (antenna_rx) {
+	case ANTENNA_SW_DIVERSITY:
+	case ANTENNA_HW_DIVERSITY:
+		rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
+		break;
+	case ANTENNA_A:
+		rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
+		rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
+		break;
+	case ANTENNA_B:
+		rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
+		rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
+		break;
+	}
+
+	rt61pci_bbp_write(rt2x00dev, 77, r77);
+	rt61pci_bbp_write(rt2x00dev, 3, r3);
+	rt61pci_bbp_write(rt2x00dev, 4, r4);
+}
+
+static void rt61pci_config_antenna_2529_rx(struct rt2x00_dev *rt2x00dev,
+					   const int p1, const int p2)
+{
+	u32 reg;
+
+	rt2x00pci_register_read(rt2x00dev, MAC_CSR13, &reg);
+
+	if (p1 != 0xff) {
+		rt2x00_set_field32(&reg, MAC_CSR13_BIT4, !!p1);
+		rt2x00_set_field32(&reg, MAC_CSR13_BIT12, 0);
+		rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg);
+	}
+	if (p2 != 0xff) {
+		rt2x00_set_field32(&reg, MAC_CSR13_BIT3, !p2);
+		rt2x00_set_field32(&reg, MAC_CSR13_BIT11, 0);
+		rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg);
+	}
+}
+
+static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev,
+					const int antenna_tx,
+					const int antenna_rx)
+{
+	u16 eeprom;
+	u8 r3;
+	u8 r4;
+	u8 r77;
+
+	rt61pci_bbp_read(rt2x00dev, 3, &r3);
+	rt61pci_bbp_read(rt2x00dev, 4, &r4);
+	rt61pci_bbp_read(rt2x00dev, 77, &r77);
+	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
+
+	rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 0);
+
+	if (rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY) &&
+	    rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY)) {
+		rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
+		rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 1);
+		rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 1);
+	} else if (rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY)) {
+		if (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED) >= 2) {
+			rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
 			rt61pci_bbp_write(rt2x00dev, 77, r77);
 		}
-	} else if (rt2x00_rf(&rt2x00dev->chip, RF2527) ||
-		   (rt2x00_rf(&rt2x00dev->chip, RF2529) &&
-		    test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags))) {
-		if (antenna_rx == ANTENNA_DIVERSITY) {
-			rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
-			rt2x00_set_field8(&r4, BBP_R4_RX_BG_MODE, 1);
-			rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
-					  test_bit(CONFIG_FRAME_TYPE,
-						   &rt2x00dev->flags));
-		} else if (antenna_rx == ANTENNA_A) {
-			rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
-			rt2x00_set_field8(&r4, BBP_R4_RX_BG_MODE, 1);
-			rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
-					  test_bit(CONFIG_FRAME_TYPE,
-						   &rt2x00dev->flags));
-			rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
+		rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
+		rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1);
+	} else if (!rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY) &&
+		   rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY)) {
+		rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
+		rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
+
+		switch (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED)) {
+		case 0:
+			rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 1);
+			break;
+		case 1:
+			rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 0);
+			break;
+		case 2:
+			rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 0);
+			break;
+		case 3:
+			rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1);
+			break;
+		}
+	} else if (!rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY) &&
+		   !rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY)) {
+		rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
+		rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
+
+		switch (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED)) {
+		case 0:
+			rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
 			rt61pci_bbp_write(rt2x00dev, 77, r77);
-		} else if (antenna_rx == ANTENNA_B) {
-			rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
-			rt2x00_set_field8(&r4, BBP_R4_RX_BG_MODE, 1);
-			rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
-					  test_bit(CONFIG_FRAME_TYPE,
-						   &rt2x00dev->flags));
+			rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 1);
+			break;
+		case 1:
 			rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
 			rt61pci_bbp_write(rt2x00dev, 77, r77);
+			rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 0);
+			break;
+		case 2:
+			rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
+			rt61pci_bbp_write(rt2x00dev, 77, r77);
+			rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 0);
+			break;
+		case 3:
+			rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
+			rt61pci_bbp_write(rt2x00dev, 77, r77);
+			rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1);
+			break;
 		}
 	}
 
+	rt61pci_bbp_write(rt2x00dev, 3, r3);
+	rt61pci_bbp_write(rt2x00dev, 4, r4);
+}
+
+struct antenna_sel {
+	u8 word;
 	/*
-	 * TODO: RF2529 with another antenna value then 2 are ignored.
-	 * The legacy driver is unclear whether in those cases there is
-	 * a possibility to switch antenna.
+	 * value[0] -> non-LNA
+	 * value[1] -> LNA
 	 */
+	u8 value[2];
+};
 
-	rt61pci_bbp_write(rt2x00dev, 3, r3);
-	rt61pci_bbp_write(rt2x00dev, 4, r4);
+static const struct antenna_sel antenna_sel_a[] = {
+	{ 96,  { 0x58, 0x78 } },
+	{ 104, { 0x38, 0x48 } },
+	{ 75,  { 0xfe, 0x80 } },
+	{ 86,  { 0xfe, 0x80 } },
+	{ 88,  { 0xfe, 0x80 } },
+	{ 35,  { 0x60, 0x60 } },
+	{ 97,  { 0x58, 0x58 } },
+	{ 98,  { 0x58, 0x58 } },
+};
+
+static const struct antenna_sel antenna_sel_bg[] = {
+	{ 96,  { 0x48, 0x68 } },
+	{ 104, { 0x2c, 0x3c } },
+	{ 75,  { 0xfe, 0x80 } },
+	{ 86,  { 0xfe, 0x80 } },
+	{ 88,  { 0xfe, 0x80 } },
+	{ 35,  { 0x50, 0x50 } },
+	{ 97,  { 0x48, 0x48 } },
+	{ 98,  { 0x48, 0x48 } },
+};
+
+static void rt61pci_config_antenna(struct rt2x00_dev *rt2x00dev,
+				   const int antenna_tx, const int antenna_rx)
+{
+	const struct antenna_sel *sel;
+	unsigned int lna;
+	unsigned int i;
+	u32 reg;
+
+	rt2x00pci_register_read(rt2x00dev, PHY_CSR0, &reg);
+
+	if (rt2x00dev->curr_hwmode == HWMODE_A) {
+		sel = antenna_sel_a;
+		lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
+
+		rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_BG, 0);
+		rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_A, 1);
+	} else {
+		sel = antenna_sel_bg;
+		lna = test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
+
+		rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_BG, 1);
+		rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_A, 0);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++)
+		rt61pci_bbp_write(rt2x00dev, sel[i].word, sel[i].value[lna]);
+
+	rt2x00pci_register_write(rt2x00dev, PHY_CSR0, reg);
+
+	if (rt2x00_rf(&rt2x00dev->chip, RF5225) ||
+	    rt2x00_rf(&rt2x00dev->chip, RF5325))
+		rt61pci_config_antenna_5x(rt2x00dev, antenna_tx, antenna_rx);
+	else if (rt2x00_rf(&rt2x00dev->chip, RF2527))
+		rt61pci_config_antenna_2x(rt2x00dev, antenna_tx, antenna_rx);
+	else if (rt2x00_rf(&rt2x00dev->chip, RF2529)) {
+		if (test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags))
+			rt61pci_config_antenna_2x(rt2x00dev, antenna_tx,
+						  antenna_rx);
+		else
+			rt61pci_config_antenna_2529(rt2x00dev, antenna_tx,
+						    antenna_rx);
+	}
 }
 
 static void rt61pci_config_duration(struct rt2x00_dev *rt2x00dev,
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h
index c47dd15..bd3e283 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.h
+++ b/drivers/net/wireless/rt2x00/rt61pci.h
@@ -332,6 +332,11 @@ struct hw_pairwise_ta_entry {
 #define MAC_CSR13_BIT5			FIELD32(0x00000020)
 #define MAC_CSR13_BIT6			FIELD32(0x00000040)
 #define MAC_CSR13_BIT7			FIELD32(0x00000080)
+#define MAC_CSR13_BIT8			FIELD32(0x00000100)
+#define MAC_CSR13_BIT9			FIELD32(0x00000200)
+#define MAC_CSR13_BIT10			FIELD32(0x00000400)
+#define MAC_CSR13_BIT11			FIELD32(0x00000800)
+#define MAC_CSR13_BIT12			FIELD32(0x00001000)
 
 /*
  * MAC_CSR14: LED control register.
@@ -1002,8 +1007,7 @@ struct hw_pairwise_ta_entry {
  * FRAME_END: 1 - DPDT, 0 - SPDT (Only valid for 802.11G, RF2527 & RF2529)
  */
 #define BBP_R4_RX_ANTENNA		FIELD8(0x03)
-#define BBP_R4_RX_FRAME_END		FIELD8(0x10)
-#define BBP_R4_RX_BG_MODE		FIELD8(0x20)
+#define BBP_R4_RX_FRAME_END		FIELD8(0x20)
 
 /*
  * R77
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 703e4e1..4aef5af 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -508,126 +508,156 @@ static void rt73usb_config_txpower(struct rt2x00_dev *rt2x00dev,
 	rt73usb_rf_write(rt2x00dev, 4, rf.rf4);
 }
 
-static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev,
-				   const int antenna_tx, const int antenna_rx)
+static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
+				      const int antenna_tx,
+				      const int antenna_rx)
 {
-	u32 reg;
 	u8 r3;
 	u8 r4;
 	u8 r77;
 
-	rt73usb_register_read(rt2x00dev, PHY_CSR0, &reg);
+	rt73usb_bbp_read(rt2x00dev, 3, &r3);
+	rt73usb_bbp_read(rt2x00dev, 4, &r4);
+	rt73usb_bbp_read(rt2x00dev, 77, &r77);
 
-	if (rt2x00dev->curr_hwmode == HWMODE_A) {
-		if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) {
-			rt73usb_bbp_write(rt2x00dev, 96, 0x78);
-			rt73usb_bbp_write(rt2x00dev, 104, 0x48);
-			rt73usb_bbp_write(rt2x00dev, 75, 0x80);
-			rt73usb_bbp_write(rt2x00dev, 86, 0x80);
-			rt73usb_bbp_write(rt2x00dev, 88, 0x80);
-		} else {
-			rt73usb_bbp_write(rt2x00dev, 96, 0x58);
-			rt73usb_bbp_write(rt2x00dev, 104, 0x38);
-			rt73usb_bbp_write(rt2x00dev, 75, 0xfe);
-			rt73usb_bbp_write(rt2x00dev, 86, 0xfe);
-			rt73usb_bbp_write(rt2x00dev, 88, 0xfe);
-		}
-		rt73usb_bbp_write(rt2x00dev, 35, 0x60);
-		rt73usb_bbp_write(rt2x00dev, 97, 0x58);
-		rt73usb_bbp_write(rt2x00dev, 98, 0x58);
+	rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 0);
 
-		rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_BG, 0);
-		rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_A, 1);
-	} else {
-		if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) {
-			rt73usb_bbp_write(rt2x00dev, 96, 0x68);
-			rt73usb_bbp_write(rt2x00dev, 104, 0x3c);
-			rt73usb_bbp_write(rt2x00dev, 75, 0x80);
-			rt73usb_bbp_write(rt2x00dev, 86, 0x80);
-			rt73usb_bbp_write(rt2x00dev, 88, 0x80);
-		} else {
-			rt73usb_bbp_write(rt2x00dev, 96, 0x48);
-			rt73usb_bbp_write(rt2x00dev, 104, 0x2c);
-			rt73usb_bbp_write(rt2x00dev, 75, 0xfe);
-			rt73usb_bbp_write(rt2x00dev, 86, 0xfe);
-			rt73usb_bbp_write(rt2x00dev, 88, 0xfe);
-		}
-		rt73usb_bbp_write(rt2x00dev, 35, 0x50);
-		rt73usb_bbp_write(rt2x00dev, 97, 0x48);
-		rt73usb_bbp_write(rt2x00dev, 98, 0x48);
+	switch (antenna_rx) {
+	case ANTENNA_SW_DIVERSITY:
+	case ANTENNA_HW_DIVERSITY:
+		rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
+		rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
+				  !!(rt2x00dev->curr_hwmode != HWMODE_A));
+		break;
+	case ANTENNA_A:
+		rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
+		rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
 
-		rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_BG, 1);
-		rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_A, 0);
+		if (rt2x00dev->curr_hwmode == HWMODE_A)
+			rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
+		else
+			rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
+		break;
+	case ANTENNA_B:
+		rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
+		rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
+
+		if (rt2x00dev->curr_hwmode == HWMODE_A)
+			rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
+		else
+			rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
+		break;
 	}
 
-	rt73usb_register_write(rt2x00dev, PHY_CSR0, reg);
+	rt73usb_bbp_write(rt2x00dev, 77, r77);
+	rt73usb_bbp_write(rt2x00dev, 3, r3);
+	rt73usb_bbp_write(rt2x00dev, 4, r4);
+}
+
+static void rt73usb_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
+				      const int antenna_tx,
+				      const int antenna_rx)
+{
+	u8 r3;
+	u8 r4;
+	u8 r77;
 
 	rt73usb_bbp_read(rt2x00dev, 3, &r3);
 	rt73usb_bbp_read(rt2x00dev, 4, &r4);
 	rt73usb_bbp_read(rt2x00dev, 77, &r77);
 
 	rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 0);
+	rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
+			  !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags));
 
-	if (rt2x00_rf(&rt2x00dev->chip, RF5226) ||
-	    rt2x00_rf(&rt2x00dev->chip, RF5225)) {
-		if (antenna_rx == ANTENNA_DIVERSITY) {
-			rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
-			if (rt2x00dev->curr_hwmode != HWMODE_A)
-				rt2x00_set_field8(&r4, BBP_R4_RX_BG_MODE, 1);
-			rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
-					  test_bit(CONFIG_FRAME_TYPE,
-						   &rt2x00dev->flags));
-		} else if (antenna_rx == ANTENNA_A) {
-			rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
-			rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
-					  test_bit(CONFIG_FRAME_TYPE,
-						   &rt2x00dev->flags));
-			if (rt2x00dev->curr_hwmode == HWMODE_A)
-				rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
-			else
-				rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
-			rt73usb_bbp_write(rt2x00dev, 77, r77);
-		} else if (antenna_rx == ANTENNA_B) {
-			rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
-			rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
-					  test_bit(CONFIG_FRAME_TYPE,
-						   &rt2x00dev->flags));
-			if (rt2x00dev->curr_hwmode == HWMODE_A)
-				rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
-			else
-				rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
-			rt73usb_bbp_write(rt2x00dev, 77, r77);
-		}
-	} else if (rt2x00_rf(&rt2x00dev->chip, RF2528) ||
-		   rt2x00_rf(&rt2x00dev->chip, RF2527)) {
-		if (antenna_rx == ANTENNA_DIVERSITY) {
-			rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
-			rt2x00_set_field8(&r4, BBP_R4_RX_BG_MODE, 1);
-			rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
-					  test_bit(CONFIG_FRAME_TYPE,
-						   &rt2x00dev->flags));
-		} else if (antenna_rx == ANTENNA_A) {
-			rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
-			rt2x00_set_field8(&r4, BBP_R4_RX_BG_MODE, 1);
-			rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
-					  test_bit(CONFIG_FRAME_TYPE,
-						   &rt2x00dev->flags));
-			rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
-			rt73usb_bbp_write(rt2x00dev, 77, r77);
-		} else if (antenna_rx == ANTENNA_B) {
-			rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
-			rt2x00_set_field8(&r4, BBP_R4_RX_BG_MODE, 1);
-			rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
-					  test_bit(CONFIG_FRAME_TYPE,
-						   &rt2x00dev->flags));
-			rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
-		}
+	switch (antenna_rx) {
+	case ANTENNA_SW_DIVERSITY:
+	case ANTENNA_HW_DIVERSITY:
+		rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
+		break;
+	case ANTENNA_A:
+		rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
+		rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
+		break;
+	case ANTENNA_B:
+		rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
+		rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
+		break;
 	}
 
+	rt73usb_bbp_write(rt2x00dev, 77, r77);
 	rt73usb_bbp_write(rt2x00dev, 3, r3);
 	rt73usb_bbp_write(rt2x00dev, 4, r4);
 }
 
+struct antenna_sel {
+	u8 word;
+	/*
+	 * value[0] -> non-LNA
+	 * value[1] -> LNA
+	 */
+	u8 value[2];
+};
+
+static const struct antenna_sel antenna_sel_a[] = {
+	{ 96,  { 0x58, 0x78 } },
+	{ 104, { 0x38, 0x48 } },
+	{ 75,  { 0xfe, 0x80 } },
+	{ 86,  { 0xfe, 0x80 } },
+	{ 88,  { 0xfe, 0x80 } },
+	{ 35,  { 0x60, 0x60 } },
+	{ 97,  { 0x58, 0x58 } },
+	{ 98,  { 0x58, 0x58 } },
+};
+
+static const struct antenna_sel antenna_sel_bg[] = {
+	{ 96,  { 0x48, 0x68 } },
+	{ 104, { 0x2c, 0x3c } },
+	{ 75,  { 0xfe, 0x80 } },
+	{ 86,  { 0xfe, 0x80 } },
+	{ 88,  { 0xfe, 0x80 } },
+	{ 35,  { 0x50, 0x50 } },
+	{ 97,  { 0x48, 0x48 } },
+	{ 98,  { 0x48, 0x48 } },
+};
+
+static void rt73usb_config_antenna(struct rt2x00_dev *rt2x00dev,
+				   const int antenna_tx, const int antenna_rx)
+{
+	const struct antenna_sel *sel;
+	unsigned int lna;
+	unsigned int i;
+	u32 reg;
+
+	rt73usb_register_read(rt2x00dev, PHY_CSR0, &reg);
+
+	if (rt2x00dev->curr_hwmode == HWMODE_A) {
+		sel = antenna_sel_a;
+		lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
+
+		rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_BG, 0);
+		rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_A, 1);
+	} else {
+		sel = antenna_sel_bg;
+		lna = test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
+
+		rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_BG, 1);
+		rt2x00_set_field32(&reg, PHY_CSR0_PA_PE_A, 0);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++)
+		rt73usb_bbp_write(rt2x00dev, sel[i].word, sel[i].value[lna]);
+
+	rt73usb_register_write(rt2x00dev, PHY_CSR0, reg);
+
+	if (rt2x00_rf(&rt2x00dev->chip, RF5226) ||
+	    rt2x00_rf(&rt2x00dev->chip, RF5225))
+		rt73usb_config_antenna_5x(rt2x00dev, antenna_tx, antenna_rx);
+	else if (rt2x00_rf(&rt2x00dev->chip, RF2528) ||
+		 rt2x00_rf(&rt2x00dev->chip, RF2527))
+		rt73usb_config_antenna_2x(rt2x00dev, antenna_tx, antenna_rx);
+}
+
 static void rt73usb_config_duration(struct rt2x00_dev *rt2x00dev,
 				    const int short_slot_time,
 				    const int beacon_int)
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h
index ec2632f..660a134 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.h
+++ b/drivers/net/wireless/rt2x00/rt73usb.h
@@ -656,8 +656,7 @@ struct hw_pairwise_ta_entry {
  * FRAME_END: 1 - DPDT, 0 - SPDT (Only valid for 802.11G, RF2527 & RF2529)
  */
 #define BBP_R4_RX_ANTENNA		FIELD8(0x03)
-#define BBP_R4_RX_FRAME_END		FIELD8(0x10)
-#define BBP_R4_RX_BG_MODE		FIELD8(0x20)
+#define BBP_R4_RX_FRAME_END		FIELD8(0x20)
 
 /*
  * R77
-- 
1.5.3

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

* [PATCH 10/24] rt2x00: Rename DEVICE_SUPPORT_ATIM to REQUIRE_BEACON_RING
       [not found] <200709161403.11332.IvDoorn@gmail.com>
                   ` (8 preceding siblings ...)
  2007-09-16 12:18 ` [PATCH 9/24] rt2x00: Rework RT61 and RT73 Antenna handling Ivo van Doorn
@ 2007-09-16 12:18 ` Ivo van Doorn
  2007-09-16 12:18 ` [PATCH 11/24] rt2x00: Remove rt2x00mac_reset() Ivo van Doorn
                   ` (13 subsequent siblings)
  23 siblings, 0 replies; 24+ messages in thread
From: Ivo van Doorn @ 2007-09-16 12:18 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, rt2400-devel

Devices that support the ATIM ring are also the devices
which require the Beacon ring to be allocated.
So by renaming the flag we can expand the meaning by
also including the beacon ring allocation to it.

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2400pci.c |    4 +-
 drivers/net/wireless/rt2x00/rt2500pci.c |    4 +-
 drivers/net/wireless/rt2x00/rt2500usb.c |    4 +-
 drivers/net/wireless/rt2x00/rt2x00.h    |   14 ++++++---
 drivers/net/wireless/rt2x00/rt2x00dev.c |   42 ++++++++++++++----------------
 5 files changed, 35 insertions(+), 33 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 5a7fc18..28236dc 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1513,9 +1513,9 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev)
 	rt2400pci_probe_hw_mode(rt2x00dev);
 
 	/*
-	 * This device supports ATIM
+	 * This device requires the beacon ring
 	 */
-	__set_bit(DEVICE_SUPPORT_ATIM, &rt2x00dev->flags);
+	__set_bit(REQUIRE_BEACON_RING, &rt2x00dev->flags);
 
 	/*
 	 * Set the rssi offset.
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index d24ea61..444e530 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1828,9 +1828,9 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev)
 	rt2500pci_probe_hw_mode(rt2x00dev);
 
 	/*
-	 * This device supports ATIM
+	 * This device requires the beacon ring
 	 */
-	__set_bit(DEVICE_SUPPORT_ATIM, &rt2x00dev->flags);
+	__set_bit(REQUIRE_BEACON_RING, &rt2x00dev->flags);
 
 	/*
 	 * Set the rssi offset.
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index f344c2a..7e8cd47 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1582,10 +1582,10 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
 
 	/*
 	 * USB devices require scheduled packet filter toggling
-	 * This device supports ATIM
+	 *This device requires the beacon ring
 	 */
 	__set_bit(PACKET_FILTER_SCHEDULED, &rt2x00dev->flags);
-	__set_bit(DEVICE_SUPPORT_ATIM, &rt2x00dev->flags);
+	__set_bit(REQUIRE_BEACON_RING, &rt2x00dev->flags);
 
 	/*
 	 * Set the rssi offset.
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 02a5adf..5ecabc8 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -516,7 +516,7 @@ struct rt2x00_dev {
 #define INTERFACE_RESET			8
 #define INTERFACE_ENABLED		9
 #define INTERFACE_ENABLED_MONITOR	10
-#define DEVICE_SUPPORT_ATIM		11
+#define REQUIRE_BEACON_RING		11
 #define DEVICE_SUPPORT_HW_BUTTON	12
 #define CONFIG_FRAME_TYPE		13
 #define CONFIG_RF_SEQUENCE		14
@@ -615,6 +615,7 @@ struct rt2x00_dev {
 	 * The Beacon array also contains the Atim ring
 	 * if that is supported by the device.
 	 */
+	int data_rings;
 	struct data_ring *rx;
 	struct data_ring *tx;
 	struct data_ring *bcn;
@@ -630,14 +631,17 @@ struct rt2x00_dev {
  * All rings have been allocated as a single array,
  * this means we can create a very simply loop macro
  * that is capable of looping through all rings.
- * ring_end() and ring_loop() are helper macro's which should
- * not be used directly. Instead the following should be used:
+ * ring_end(), txring_end() and ring_loop() are helper macro's which
+ * should not be used directly. Instead the following should be used:
  * ring_for_each() - Loops through all rings (RX, TX, Beacon & Atim)
  * txring_for_each() - Loops through TX data rings (TX only)
  * txringall_for_each() - Loops through all TX rings (TX, Beacon & Atim)
  */
 #define ring_end(__dev) \
-	&(__dev)->bcn[1 + test_bit(DEVICE_SUPPORT_ATIM, &rt2x00dev->flags)]
+	&(__dev)->rx[(__dev)->data_rings]
+
+#define txring_end(__dev) \
+	&(__dev)->tx[(__dev)->hw->queues]
 
 #define ring_loop(__entry, __start, __end)			\
 	for ((__entry) = (__start);				\
@@ -648,7 +652,7 @@ struct rt2x00_dev {
 	ring_loop(__entry, (__dev)->rx, ring_end(__dev))
 
 #define txring_for_each(__dev, __entry) \
-	ring_loop(__entry, (__dev)->tx, (__dev)->bcn)
+	ring_loop(__entry, (__dev)->tx, txring_end(__dev))
 
 #define txringall_for_each(__dev, __entry) \
 	ring_loop(__entry, (__dev)->tx, ring_end(__dev))
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index fed2cce..81458bf 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -40,24 +40,22 @@
 struct data_ring *rt2x00lib_get_ring(struct rt2x00_dev *rt2x00dev,
 				     const unsigned int queue)
 {
-	int atim = test_bit(DEVICE_SUPPORT_ATIM, &rt2x00dev->flags);
-
-	/*
-	 * Check if the rings have been allocated.
-	 */
-	if (!rt2x00dev->tx || !rt2x00dev->bcn)
-		return NULL;
+	int beacon = test_bit(REQUIRE_BEACON_RING, &rt2x00dev->flags);
 
 	/*
 	 * Check if we are requesting a reqular TX ring,
 	 * or if we are requesting a Beacon or Atim ring.
 	 * For Atim rings, we should check if it is supported.
 	 */
-	if (queue < rt2x00dev->hw->queues)
+	if (queue < rt2x00dev->hw->queues && rt2x00dev->tx)
 		return &rt2x00dev->tx[queue];
-	else if (queue == IEEE80211_TX_QUEUE_BEACON)
+
+	if (!rt2x00dev->bcn || !beacon)
+		return NULL;
+
+	if (queue == IEEE80211_TX_QUEUE_BEACON)
 		return &rt2x00dev->bcn[0];
-	else if (queue == IEEE80211_TX_QUEUE_AFTER_BEACON && atim)
+	else if (queue == IEEE80211_TX_QUEUE_AFTER_BEACON)
 		return &rt2x00dev->bcn[1];
 
 	return NULL;
@@ -790,6 +788,9 @@ static int rt2x00lib_alloc_ring_entries(struct rt2x00_dev *rt2x00dev)
 			return -ENOMEM;
 	}
 
+	if (!test_bit(REQUIRE_BEACON_RING, &rt2x00dev->flags))
+		return 0;
+
 	/*
 	 * Allocate the BEACON ring.
 	 */
@@ -800,9 +801,6 @@ static int rt2x00lib_alloc_ring_entries(struct rt2x00_dev *rt2x00dev)
 	/*
 	 * Allocate the Atim ring.
 	 */
-	if (!test_bit(DEVICE_SUPPORT_ATIM, &rt2x00dev->flags))
-		return 0;
-
 	if (rt2x00lib_alloc_entries(&rt2x00dev->bcn[1], ATIM_ENTRIES,
 				    DATA_FRAME_SIZE, rt2x00dev->ops->txd_size))
 		return -ENOMEM;
@@ -960,19 +958,18 @@ void rt2x00lib_deinit_interface(struct rt2x00_dev *rt2x00dev)
 static int rt2x00lib_alloc_rings(struct rt2x00_dev *rt2x00dev)
 {
 	struct data_ring *ring;
-	unsigned int ring_num;
 
 	/*
 	 * We need the following rings:
 	 * RX: 1
 	 * TX: hw->queues
-	 * Beacon: 1
-	 * Atim: 1 (if supported)
+	 * Beacon: 1 (if required)
+	 * Atim: 1 (if required)
 	 */
-	ring_num = 2 + rt2x00dev->hw->queues +
-	    test_bit(DEVICE_SUPPORT_ATIM, &rt2x00dev->flags);
+	rt2x00dev->data_rings = 1 + rt2x00dev->hw->queues +
+	    (2 * test_bit(REQUIRE_BEACON_RING, &rt2x00dev->flags));
 
-	ring = kzalloc(sizeof(*ring) * ring_num, GFP_KERNEL);
+	ring = kzalloc(rt2x00dev->data_rings * sizeof(*ring), GFP_KERNEL);
 	if (!ring) {
 		ERROR(rt2x00dev, "Ring allocation failed.\n");
 		return -ENOMEM;
@@ -981,9 +978,10 @@ static int rt2x00lib_alloc_rings(struct rt2x00_dev *rt2x00dev)
 	/*
 	 * Initialize pointers
 	 */
-	rt2x00dev->rx = &ring[0];
-	rt2x00dev->tx = &ring[1];
-	rt2x00dev->bcn = &ring[1 + rt2x00dev->hw->queues];
+	rt2x00dev->rx = ring;
+	rt2x00dev->tx = &rt2x00dev->rx[1];
+	if (test_bit(REQUIRE_BEACON_RING, &rt2x00dev->flags))
+		rt2x00dev->bcn = &rt2x00dev->tx[rt2x00dev->hw->queues];
 
 	/*
 	 * Initialize ring parameters.
-- 
1.5.3

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

* [PATCH 11/24] rt2x00: Remove rt2x00mac_reset()
       [not found] <200709161403.11332.IvDoorn@gmail.com>
                   ` (9 preceding siblings ...)
  2007-09-16 12:18 ` [PATCH 10/24] rt2x00: Rename DEVICE_SUPPORT_ATIM to REQUIRE_BEACON_RING Ivo van Doorn
@ 2007-09-16 12:18 ` Ivo van Doorn
  2007-09-16 12:18 ` [PATCH 12/24] rt2x00: Fix system freeze on device removal Ivo van Doorn
                   ` (12 subsequent siblings)
  23 siblings, 0 replies; 24+ messages in thread
From: Ivo van Doorn @ 2007-09-16 12:18 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, rt2400-devel

rt2x00mac_reset() only had a single caller which
didn't require the shutdown part of the function.
This means the time has come to remove the function
completely and have the resume handler perform all
tasks itself.

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2x00.h       |    3 +-
 drivers/net/wireless/rt2x00/rt2x00config.c |   12 +++---
 drivers/net/wireless/rt2x00/rt2x00dev.c    |   49 ++++++++++++++++++++++-----
 drivers/net/wireless/rt2x00/rt2x00mac.c    |   47 --------------------------
 4 files changed, 47 insertions(+), 64 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 5ecabc8..b5f408c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -513,7 +513,7 @@ struct rt2x00_dev {
 #define REQUIRE_FIRMWARE		5
 #define PACKET_FILTER_SCHEDULED		6
 #define PACKET_FILTER_PENDING		7
-#define INTERFACE_RESET			8
+#define INTERFACE_RESUME		8
 #define INTERFACE_ENABLED		9
 #define INTERFACE_ENABLED_MONITOR	10
 #define REQUIRE_BEACON_RING		11
@@ -776,7 +776,6 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
  */
 int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
 		 struct ieee80211_tx_control *control);
-int rt2x00mac_reset(struct ieee80211_hw *hw);
 int rt2x00mac_add_interface(struct ieee80211_hw *hw,
 			    struct ieee80211_if_init_conf *conf);
 void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index b5075b5..de890a1 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -50,10 +50,10 @@ void rt2x00lib_config_packet_filter(struct rt2x00_dev *rt2x00dev, int filter)
 {
 	/*
 	 * Only configure the device when something has changed,
-	 * or if we are in RESET state in which case all configuration
+	 * or if we are in RESUME state in which case all configuration
 	 * will be forced upon the device.
 	 */
-	if (!test_bit(INTERFACE_RESET, &rt2x00dev->flags) &&
+	if (!test_bit(INTERFACE_RESUME, &rt2x00dev->flags) &&
 	    !test_bit(PACKET_FILTER_PENDING, &rt2x00dev->flags))
 		return;
 
@@ -82,10 +82,10 @@ void rt2x00lib_config_type(struct rt2x00_dev *rt2x00dev, int type)
 
 	/*
 	 * Only configure the device when something has changed,
-	 * or if we are in RESET state in which case all configuration
+	 * or if we are in RESUME state in which case all configuration
 	 * will be forced upon the device.
 	 */
-	if (!test_bit(INTERFACE_RESET, &rt2x00dev->flags) &&
+	if (!test_bit(INTERFACE_RESUME, &rt2x00dev->flags) &&
 	    (!(is_interface_present(intf) ^
 	       test_bit(INTERFACE_ENABLED, &rt2x00dev->flags)) &&
 	     !(is_monitor_present(intf) ^
@@ -119,10 +119,10 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, struct ieee80211_conf *conf)
 	int flags = 0;
 
 	/*
-	 * If we are in RESET state we should
+	 * If we are in RESUME state we should
 	 * force all configuration options.
 	 */
-	if (test_bit(INTERFACE_RESET, &rt2x00dev->flags)) {
+	if (test_bit(INTERFACE_RESUME, &rt2x00dev->flags)) {
 		flags = CONFIG_UPDATE_ALL;
 		goto config;
 	}
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 81458bf..7730d9d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -944,12 +944,6 @@ void rt2x00lib_deinit_interface(struct rt2x00_dev *rt2x00dev)
 		rt2x00lib_config_bssid(rt2x00dev, intf->bssid);
 		rt2x00lib_config_type(rt2x00dev, intf->type);
 	}
-
-	/*
-	 * If we are in reset mode, the device must be deinitialized.
-	 */
-	if (test_bit(INTERFACE_RESET, &rt2x00dev->flags))
-		rt2x00lib_uninitialize(rt2x00dev);
 }
 
 /*
@@ -1136,7 +1130,11 @@ EXPORT_SYMBOL_GPL(rt2x00lib_suspend);
 
 int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
 {
+	struct interface *intf = &rt2x00dev->interface;
+	int retval;
+
 	NOTICE(rt2x00dev, "Waking up.\n");
+	__set_bit(INTERFACE_RESUME, &rt2x00dev->flags);
 
 	/*
 	 * Open the debugfs entry.
@@ -1144,10 +1142,43 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
 	rt2x00debug_register(rt2x00dev);
 
 	/*
-	 * The reset handler can take care of bringing the
-	 * device back into a workable state.
+	 * Reinitialize device and all active interfaces.
+	 */
+	retval = rt2x00lib_init_interface(rt2x00dev);
+	if (retval)
+		goto exit;
+
+	/*
+	 * Reconfigure device.
+	 */
+	retval = rt2x00mac_config(rt2x00dev->hw, &rt2x00dev->hw->conf);
+	if (retval)
+		goto exit;
+
+	rt2x00lib_config_type(rt2x00dev, intf->type);
+	rt2x00lib_config_packet_filter(rt2x00dev, intf->filter);
+	rt2x00lib_config_bssid(rt2x00dev, intf->bssid);
+
+	/*
+	 * When in Master or Ad-hoc mode,
+	 * restart Beacon transmitting by faking a beacondone event.
 	 */
-	return rt2x00mac_reset(rt2x00dev->hw);
+	if (intf->type == IEEE80211_IF_TYPE_AP ||
+	    intf->type == IEEE80211_IF_TYPE_IBSS)
+		rt2x00lib_beacondone(rt2x00dev);
+
+	__clear_bit(INTERFACE_RESUME, &rt2x00dev->flags);
+
+	return 0;
+
+exit:
+	rt2x00lib_disable_radio(rt2x00dev);
+	rt2x00lib_uninitialize(rt2x00dev);
+	rt2x00debug_deregister(rt2x00dev);
+
+	__clear_bit(INTERFACE_RESUME, &rt2x00dev->flags);
+
+	return retval;
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_resume);
 
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 0001b79..006154c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -121,53 +121,6 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
 }
 EXPORT_SYMBOL_GPL(rt2x00mac_tx);
 
-int rt2x00mac_reset(struct ieee80211_hw *hw)
-{
-	struct rt2x00_dev *rt2x00dev = hw->priv;
-	struct interface *intf = &rt2x00dev->interface;
-	int retval;
-
-	NOTICE(rt2x00dev, "Entering reset state.\n");
-	__set_bit(INTERFACE_RESET, &rt2x00dev->flags);
-
-	/*
-	 * Disable radio and unitialize all items
-	 * that we will recreate to reset the device.
-	 */
-	rt2x00lib_disable_radio(rt2x00dev);
-	rt2x00lib_deinit_interface(rt2x00dev);
-
-	/*
-	 * Reinitialize device and all active interfaces.
-	 */
-	retval = rt2x00lib_init_interface(rt2x00dev);
-	if (retval)
-		goto exit;
-
-	/*
-	 * Reconfigure device.
-	 */
-	rt2x00lib_config(rt2x00dev, &hw->conf);
-	rt2x00lib_config_type(rt2x00dev, intf->type);
-	rt2x00lib_config_packet_filter(rt2x00dev, intf->filter);
-	rt2x00lib_config_bssid(rt2x00dev, intf->bssid);
-
-	/*
-	 * When in Master or Ad-hoc mode,
-	 * restart Beacon transmitting by faking a beacondone event.
-	 */
-	if (intf->type == IEEE80211_IF_TYPE_AP ||
-	    intf->type == IEEE80211_IF_TYPE_IBSS)
-		rt2x00lib_beacondone(rt2x00dev);
-
-exit:
-	__clear_bit(INTERFACE_RESET, &rt2x00dev->flags);
-	NOTICE(rt2x00dev, "Device reset %s.\n",
-	       retval ? "failed" : "succeeded");
-
-	return retval;
-}
-
 int rt2x00mac_add_interface(struct ieee80211_hw *hw,
 			    struct ieee80211_if_init_conf *conf)
 {
-- 
1.5.3

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

* [PATCH 12/24] rt2x00: Fix system freeze on device removal
       [not found] <200709161403.11332.IvDoorn@gmail.com>
                   ` (10 preceding siblings ...)
  2007-09-16 12:18 ` [PATCH 11/24] rt2x00: Remove rt2x00mac_reset() Ivo van Doorn
@ 2007-09-16 12:18 ` Ivo van Doorn
  2007-09-16 12:18 ` [PATCH 13/24] rt2x00: Reduce magic value writing to device Ivo van Doorn
                   ` (11 subsequent siblings)
  23 siblings, 0 replies; 24+ messages in thread
From: Ivo van Doorn @ 2007-09-16 12:18 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, rt2400-devel

When a PCI device is unplugged reading from the
register will return the value from the state of just
before the device is unplugged.

When a rt61pci device was removed while the txdone
handler was running it ended in a endless loop because
it would run the txdone handler from the same frame
(the one last indicated by STA_CSR4) over and over again.

Check in the loop if the freshly read register value is
the same as the previously one and bail out if this is the case.

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
 drivers/net/wireless/rt2x00/rt61pci.c |   22 ++++++++++++++++++----
 1 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 6199606..0c53b61 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1801,23 +1801,37 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev)
 	struct data_desc *txd;
 	u32 word;
 	u32 reg;
+	u32 old_reg;
+	int type;
 	int index;
 	int tx_status;
 	int retry;
 
+	/*
+	 * During each loop we will compare the freshly read
+	 * STA_CSR4 register value with the value read from
+	 * the previous loop. If the 2 values are equal then
+	 * we should stop processing because the chance it
+	 * quite big that the device has been unplugged and
+	 * we risk going into an endless loop.
+	 */
+	old_reg = 0;
+
 	while (1) {
 		rt2x00pci_register_read(rt2x00dev, STA_CSR4, &reg);
 		if (!rt2x00_get_field32(reg, STA_CSR4_VALID))
 			break;
 
+		if (old_reg == reg)
+			break;
+		old_reg = reg;
+
 		/*
 		 * Skip this entry when it contains an invalid
 		 * ring identication number.
 		 */
-		ring =
-		    rt2x00lib_get_ring(rt2x00dev,
-				       rt2x00_get_field32(reg,
-							  STA_CSR4_PID_TYPE));
+		type = rt2x00_get_field32(reg, STA_CSR4_PID_TYPE);
+		ring = rt2x00lib_get_ring(rt2x00dev, type);
 		if (unlikely(!ring))
 			continue;
 
-- 
1.5.3

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

* [PATCH 13/24] rt2x00: Reduce magic value writing to device
       [not found] <200709161403.11332.IvDoorn@gmail.com>
                   ` (11 preceding siblings ...)
  2007-09-16 12:18 ` [PATCH 12/24] rt2x00: Fix system freeze on device removal Ivo van Doorn
@ 2007-09-16 12:18 ` Ivo van Doorn
  2007-09-16 12:19 ` [PATCH 14/24] rt2x00: New USB ID's for rt73usb and rt2500usb Ivo van Doorn
                   ` (10 subsequent siblings)
  23 siblings, 0 replies; 24+ messages in thread
From: Ivo van Doorn @ 2007-09-16 12:18 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, rt2400-devel

By looking closely to the legacy drivers, and most notably the comments,
comparison between similar chipsets (rt2500pci-rt2500usb rt61pci-rt73usb),
and straightout guessing we can now add quite a lot of register definitions
and split the magical value up into more logical values or at least make
them slightly less magical.

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2500pci.c |   39 +++++++++++---
 drivers/net/wireless/rt2x00/rt2500pci.h |   40 ++++++++++----
 drivers/net/wireless/rt2x00/rt2500usb.c |   56 ++++++++++++++++---
 drivers/net/wireless/rt2x00/rt2500usb.h |   39 ++++++++++++--
 drivers/net/wireless/rt2x00/rt61pci.c   |   88 +++++++++++++++++++++++++++---
 drivers/net/wireless/rt2x00/rt61pci.h   |   77 ++++++++++++++++++++++++++-
 drivers/net/wireless/rt2x00/rt73usb.c   |   60 +++++++++++++++++++--
 drivers/net/wireless/rt2x00/rt73usb.h   |   60 +++++++++++++++++++++-
 8 files changed, 408 insertions(+), 51 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 444e530..fc28631 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -930,24 +930,45 @@ static int rt2500pci_init_registers(struct rt2x00_dev *rt2x00dev)
 	rt2x00pci_register_write(rt2x00dev, CNT3, 0);
 
 	rt2x00pci_register_read(rt2x00dev, TXCSR8, &reg);
-	rt2x00_set_field32(&reg, TXCSR8_CCK_SIGNAL, 0x8a);
-	rt2x00_set_field32(&reg, TXCSR8_CCK_SERVICE, 0x8b);
-	rt2x00_set_field32(&reg, TXCSR8_CCK_LENGTH_LOW, 0x8d);
-	rt2x00_set_field32(&reg, TXCSR8_CCK_LENGTH_HIGH, 0x8c);
+	rt2x00_set_field32(&reg, TXCSR8_BBP_ID0, 10);
+	rt2x00_set_field32(&reg, TXCSR8_BBP_ID0_VALID, 1);
+	rt2x00_set_field32(&reg, TXCSR8_BBP_ID1, 11);
+	rt2x00_set_field32(&reg, TXCSR8_BBP_ID1_VALID, 1);
+	rt2x00_set_field32(&reg, TXCSR8_BBP_ID2, 13);
+	rt2x00_set_field32(&reg, TXCSR8_BBP_ID2_VALID, 1);
+	rt2x00_set_field32(&reg, TXCSR8_BBP_ID3, 12);
+	rt2x00_set_field32(&reg, TXCSR8_BBP_ID3_VALID, 1);
 	rt2x00pci_register_write(rt2x00dev, TXCSR8, reg);
 
-	rt2x00pci_register_write(rt2x00dev, ARTCSR0, 0x7038140a);
-	rt2x00pci_register_write(rt2x00dev, ARTCSR1, 0x1d21252d);
-	rt2x00pci_register_write(rt2x00dev, ARTCSR2, 0x1919191d);
+	rt2x00pci_register_read(rt2x00dev, ARTCSR0, &reg);
+	rt2x00_set_field32(&reg, ARTCSR0_ACK_CTS_1MBS, 112);
+	rt2x00_set_field32(&reg, ARTCSR0_ACK_CTS_2MBS, 56);
+	rt2x00_set_field32(&reg, ARTCSR0_ACK_CTS_5_5MBS, 20);
+	rt2x00_set_field32(&reg, ARTCSR0_ACK_CTS_11MBS, 10);
+	rt2x00pci_register_write(rt2x00dev, ARTCSR0, reg);
+
+	rt2x00pci_register_read(rt2x00dev, ARTCSR1, &reg);
+	rt2x00_set_field32(&reg, ARTCSR1_ACK_CTS_6MBS, 45);
+	rt2x00_set_field32(&reg, ARTCSR1_ACK_CTS_9MBS, 37);
+	rt2x00_set_field32(&reg, ARTCSR1_ACK_CTS_12MBS, 33);
+	rt2x00_set_field32(&reg, ARTCSR1_ACK_CTS_18MBS, 29);
+	rt2x00pci_register_write(rt2x00dev, ARTCSR1, reg);
+
+	rt2x00pci_register_read(rt2x00dev, ARTCSR2, &reg);
+	rt2x00_set_field32(&reg, ARTCSR2_ACK_CTS_24MBS, 29);
+	rt2x00_set_field32(&reg, ARTCSR2_ACK_CTS_36MBS, 25);
+	rt2x00_set_field32(&reg, ARTCSR2_ACK_CTS_48MBS, 25);
+	rt2x00_set_field32(&reg, ARTCSR2_ACK_CTS_54MBS, 25);
+	rt2x00pci_register_write(rt2x00dev, ARTCSR2, reg);
 
 	rt2x00pci_register_read(rt2x00dev, RXCSR3, &reg);
-	rt2x00_set_field32(&reg, RXCSR3_BBP_ID0, 47); /* Signal */
+	rt2x00_set_field32(&reg, RXCSR3_BBP_ID0, 47); /* CCK Signal */
 	rt2x00_set_field32(&reg, RXCSR3_BBP_ID0_VALID, 1);
 	rt2x00_set_field32(&reg, RXCSR3_BBP_ID1, 51); /* Rssi */
 	rt2x00_set_field32(&reg, RXCSR3_BBP_ID1_VALID, 1);
 	rt2x00_set_field32(&reg, RXCSR3_BBP_ID2, 42); /* OFDM Rate */
 	rt2x00_set_field32(&reg, RXCSR3_BBP_ID2_VALID, 1);
-	rt2x00_set_field32(&reg, RXCSR3_BBP_ID3, 51); /* OFDM */
+	rt2x00_set_field32(&reg, RXCSR3_BBP_ID3, 51); /* RSSI */
 	rt2x00_set_field32(&reg, RXCSR3_BBP_ID3_VALID, 1);
 	rt2x00pci_register_write(rt2x00dev, RXCSR3, reg);
 
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h
index 5db6cde..d92aa56 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.h
+++ b/drivers/net/wireless/rt2x00/rt2500pci.h
@@ -440,16 +440,16 @@
 
 /*
  * TXCSR8: CCK Tx BBP register.
- * CCK_SIGNAL: BBP rate field address for CCK.
- * CCK_SERVICE: BBP service field address for CCK.
- * CCK_LENGTH_LOW: BBP length low byte address for CCK.
- * CCK_LENGTH_HIGH: BBP length high byte address for CCK.
  */
 #define TXCSR8				0x0098
-#define TXCSR8_CCK_SIGNAL		FIELD32(0x000000ff)
-#define TXCSR8_CCK_SERVICE		FIELD32(0x0000ff00)
-#define TXCSR8_CCK_LENGTH_LOW		FIELD32(0x00ff0000)
-#define TXCSR8_CCK_LENGTH_HIGH		FIELD32(0xff000000)
+#define TXCSR8_BBP_ID0			FIELD32(0x0000007f)
+#define TXCSR8_BBP_ID0_VALID		FIELD32(0x00000080)
+#define TXCSR8_BBP_ID1			FIELD32(0x00007f00)
+#define TXCSR8_BBP_ID1_VALID		FIELD32(0x00008000)
+#define TXCSR8_BBP_ID2			FIELD32(0x007f0000)
+#define TXCSR8_BBP_ID2_VALID		FIELD32(0x00800000)
+#define TXCSR8_BBP_ID3			FIELD32(0x7f000000)
+#define TXCSR8_BBP_ID3_VALID		FIELD32(0x80000000)
 
 /*
  * TXCSR9: OFDM TX BBP registers
@@ -864,14 +864,32 @@
 #define ARCSR5_LENGTH			FIELD32(0xffff0000)
 
 /*
- * ACK/CTS payload consumed time registers.
  * ARTCSR0: CCK ACK/CTS payload consumed time for 1/2/5.5/11 mbps.
- * ARTCSR1: OFDM ACK/CTS payload consumed time for 6/9/12/18 mbps.
- * ARTCSR2: OFDM ACK/CTS payload consumed time for 24/36/48/54 mbps.
  */
 #define ARTCSR0				0x014c
+#define ARTCSR0_ACK_CTS_11MBS		FIELD32(0x000000ff)
+#define ARTCSR0_ACK_CTS_5_5MBS		FIELD32(0x0000ff00)
+#define ARTCSR0_ACK_CTS_2MBS		FIELD32(0x00ff0000)
+#define ARTCSR0_ACK_CTS_1MBS		FIELD32(0xff000000)
+
+
+/*
+ * ARTCSR1: OFDM ACK/CTS payload consumed time for 6/9/12/18 mbps.
+ */
 #define ARTCSR1				0x0150
+#define ARTCSR1_ACK_CTS_6MBS		FIELD32(0x000000ff)
+#define ARTCSR1_ACK_CTS_9MBS		FIELD32(0x0000ff00)
+#define ARTCSR1_ACK_CTS_12MBS		FIELD32(0x00ff0000)
+#define ARTCSR1_ACK_CTS_18MBS		FIELD32(0xff000000)
+
+/*
+ * ARTCSR2: OFDM ACK/CTS payload consumed time for 24/36/48/54 mbps.
+ */
 #define ARTCSR2				0x0154
+#define ARTCSR2_ACK_CTS_24MBS		FIELD32(0x000000ff)
+#define ARTCSR2_ACK_CTS_36MBS		FIELD32(0x0000ff00)
+#define ARTCSR2_ACK_CTS_48MBS		FIELD32(0x00ff0000)
+#define ARTCSR2_ACK_CTS_54MBS		FIELD32(0xff000000)
 
 /*
  * SECCSR1_RT2509: WEP control register.
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 7e8cd47..2c2d8b7 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -796,20 +796,57 @@ static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev)
 	rt2500usb_register_write(rt2x00dev, MAC_CSR13, 0x1111);
 	rt2500usb_register_write(rt2x00dev, MAC_CSR14, 0x1e11);
 
-	rt2500usb_register_write(rt2x00dev, MAC_CSR1, 0x0003);
-	rt2500usb_register_write(rt2x00dev, MAC_CSR1, 0x0000);
+	rt2500usb_register_read(rt2x00dev, MAC_CSR1, &reg);
+	rt2x00_set_field16(&reg, MAC_CSR1_SOFT_RESET, 1);
+	rt2x00_set_field16(&reg, MAC_CSR1_BBP_RESET, 1);
+	rt2x00_set_field16(&reg, MAC_CSR1_HOST_READY, 0);
+	rt2500usb_register_write(rt2x00dev, MAC_CSR1, reg);
+
+	rt2500usb_register_read(rt2x00dev, MAC_CSR1, &reg);
+	rt2x00_set_field16(&reg, MAC_CSR1_SOFT_RESET, 0);
+	rt2x00_set_field16(&reg, MAC_CSR1_BBP_RESET, 0);
+	rt2x00_set_field16(&reg, MAC_CSR1_HOST_READY, 0);
+	rt2500usb_register_write(rt2x00dev, MAC_CSR1, reg);
+
+	rt2500usb_register_read(rt2x00dev, TXRX_CSR5, &reg);
+	rt2x00_set_field16(&reg, TXRX_CSR5_BBP_ID0, 13);
+	rt2x00_set_field16(&reg, TXRX_CSR5_BBP_ID0_VALID, 1);
+	rt2x00_set_field16(&reg, TXRX_CSR5_BBP_ID1, 12);
+	rt2x00_set_field16(&reg, TXRX_CSR5_BBP_ID1_VALID, 1);
+	rt2500usb_register_write(rt2x00dev, TXRX_CSR5, reg);
+
+	rt2500usb_register_read(rt2x00dev, TXRX_CSR6, &reg);
+	rt2x00_set_field16(&reg, TXRX_CSR6_BBP_ID0, 10);
+	rt2x00_set_field16(&reg, TXRX_CSR6_BBP_ID0_VALID, 1);
+	rt2x00_set_field16(&reg, TXRX_CSR6_BBP_ID1, 11);
+	rt2x00_set_field16(&reg, TXRX_CSR6_BBP_ID1_VALID, 1);
+	rt2500usb_register_write(rt2x00dev, TXRX_CSR6, reg);
+
+	rt2500usb_register_read(rt2x00dev, TXRX_CSR7, &reg);
+	rt2x00_set_field16(&reg, TXRX_CSR7_BBP_ID0, 7);
+	rt2x00_set_field16(&reg, TXRX_CSR7_BBP_ID0_VALID, 1);
+	rt2x00_set_field16(&reg, TXRX_CSR7_BBP_ID1, 6);
+	rt2x00_set_field16(&reg, TXRX_CSR7_BBP_ID1_VALID, 1);
+	rt2500usb_register_write(rt2x00dev, TXRX_CSR7, reg);
+
+	rt2500usb_register_read(rt2x00dev, TXRX_CSR8, &reg);
+	rt2x00_set_field16(&reg, TXRX_CSR8_BBP_ID0, 5);
+	rt2x00_set_field16(&reg, TXRX_CSR8_BBP_ID0_VALID, 1);
+	rt2x00_set_field16(&reg, TXRX_CSR8_BBP_ID1, 0);
+	rt2x00_set_field16(&reg, TXRX_CSR8_BBP_ID1_VALID, 0);
+	rt2500usb_register_write(rt2x00dev, TXRX_CSR8, reg);
 
-	rt2500usb_register_write(rt2x00dev, TXRX_CSR5, 0x8c8d);
-	rt2500usb_register_write(rt2x00dev, TXRX_CSR6, 0x8b8a);
-	rt2500usb_register_write(rt2x00dev, TXRX_CSR7, 0x8687);
-	rt2500usb_register_write(rt2x00dev, TXRX_CSR8, 0x0085);
 	rt2500usb_register_write(rt2x00dev, TXRX_CSR21, 0xe78f);
 	rt2500usb_register_write(rt2x00dev, MAC_CSR9, 0xff1d);
 
 	if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE))
 		return -EBUSY;
 
-	rt2500usb_register_write(rt2x00dev, MAC_CSR1, 0x0004);
+	rt2500usb_register_read(rt2x00dev, MAC_CSR1, &reg);
+	rt2x00_set_field16(&reg, MAC_CSR1_SOFT_RESET, 0);
+	rt2x00_set_field16(&reg, MAC_CSR1_BBP_RESET, 0);
+	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) {
 		rt2500usb_register_read(rt2x00dev, PHY_CSR2, &reg);
@@ -835,11 +872,12 @@ static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev)
 	rt2500usb_register_write(rt2x00dev, TXRX_CSR0, reg);
 
 	rt2500usb_register_read(rt2x00dev, MAC_CSR18, &reg);
-	rt2x00_set_field16(&reg, MAC_CSR18_DELAY_AFTER_BEACON, 0x5a);
+	rt2x00_set_field16(&reg, MAC_CSR18_DELAY_AFTER_BEACON, 90);
 	rt2500usb_register_write(rt2x00dev, MAC_CSR18, reg);
 
 	rt2500usb_register_read(rt2x00dev, PHY_CSR4, &reg);
-	rt2500usb_register_write(rt2x00dev, PHY_CSR4, reg | 0x0001);
+	rt2x00_set_field16(&reg, PHY_CSR4_LOW_RF_LE, 1);
+	rt2500usb_register_write(rt2x00dev, PHY_CSR4, reg);
 
 	rt2500usb_register_read(rt2x00dev, TXRX_CSR1, &reg);
 	rt2x00_set_field16(&reg, TXRX_CSR1_AUTO_SEQUENCE, 1);
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h
index b5033da..b18d56e 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.h
+++ b/drivers/net/wireless/rt2x00/rt2500usb.h
@@ -74,8 +74,14 @@
 
 /*
  * MAC_CSR1: System control.
+ * SOFT_RESET: Software reset, 1: reset, 0: normal.
+ * BBP_RESET: Hardware reset, 1: reset, 0, release.
+ * HOST_READY: Host ready after initialization.
  */
 #define MAC_CSR1			0x0402
+#define MAC_CSR1_SOFT_RESET		FIELD16(0x00000001)
+#define MAC_CSR1_BBP_RESET		FIELD16(0x00000002)
+#define MAC_CSR1_HOST_READY		FIELD16(0x00000004)
 
 /*
  * MAC_CSR2: STA MAC register 0.
@@ -260,16 +266,40 @@
 #define TXRX_CSR4			0x0448
 
 /*
- * TX BBP ID registers
  * TXRX_CSR5: CCK TX BBP ID0.
- * TXRX_CSR5: CCK TX BBP ID1.
- * TXRX_CSR5: OFDM TX BBP ID0.
- * TXRX_CSR5: OFDM TX BBP ID1.
  */
 #define TXRX_CSR5			0x044a
+#define TXRX_CSR5_BBP_ID0		FIELD16(0x007f)
+#define TXRX_CSR5_BBP_ID0_VALID		FIELD16(0x0080)
+#define TXRX_CSR5_BBP_ID1		FIELD16(0x7f00)
+#define TXRX_CSR5_BBP_ID1_VALID		FIELD16(0x8000)
+
+/*
+ * TXRX_CSR6: CCK TX BBP ID1.
+ */
 #define TXRX_CSR6			0x044c
+#define TXRX_CSR6_BBP_ID0		FIELD16(0x007f)
+#define TXRX_CSR6_BBP_ID0_VALID		FIELD16(0x0080)
+#define TXRX_CSR6_BBP_ID1		FIELD16(0x7f00)
+#define TXRX_CSR6_BBP_ID1_VALID		FIELD16(0x8000)
+
+/*
+ * TXRX_CSR7: OFDM TX BBP ID0.
+ */
 #define TXRX_CSR7			0x044e
+#define TXRX_CSR7_BBP_ID0		FIELD16(0x007f)
+#define TXRX_CSR7_BBP_ID0_VALID		FIELD16(0x0080)
+#define TXRX_CSR7_BBP_ID1		FIELD16(0x7f00)
+#define TXRX_CSR7_BBP_ID1_VALID		FIELD16(0x8000)
+
+/*
+ * TXRX_CSR5: OFDM TX BBP ID1.
+ */
 #define TXRX_CSR8			0x0450
+#define TXRX_CSR8_BBP_ID0		FIELD16(0x007f)
+#define TXRX_CSR8_BBP_ID0_VALID		FIELD16(0x0080)
+#define TXRX_CSR8_BBP_ID1		FIELD16(0x7f00)
+#define TXRX_CSR8_BBP_ID1_VALID		FIELD16(0x8000)
 
 /*
  * TXRX_CSR9: TX ACK time-out.
@@ -410,6 +440,7 @@
  * PHY_CSR4: Interface configuration.
  */
 #define PHY_CSR4			0x04c8
+#define PHY_CSR4_LOW_RF_LE		FIELD16(0x0001)
 
 /*
  * BBP pre-TX registers.
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 0c53b61..a2d852f 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1287,9 +1287,25 @@ static int rt61pci_init_rings(struct rt2x00_dev *rt2x00dev)
 			   rt2x00dev->rx->data_dma);
 	rt2x00pci_register_write(rt2x00dev, RX_BASE_CSR, reg);
 
-	rt2x00pci_register_write(rt2x00dev, TX_DMA_DST_CSR, 0x000000aa);
-	rt2x00pci_register_write(rt2x00dev, LOAD_TX_RING_CSR, 0x0000001f);
-	rt2x00pci_register_write(rt2x00dev, RX_CNTL_CSR, 0x00000002);
+	rt2x00pci_register_read(rt2x00dev, TX_DMA_DST_CSR, &reg);
+	rt2x00_set_field32(&reg, TX_DMA_DST_CSR_DEST_AC0, 2);
+	rt2x00_set_field32(&reg, TX_DMA_DST_CSR_DEST_AC1, 2);
+	rt2x00_set_field32(&reg, TX_DMA_DST_CSR_DEST_AC2, 2);
+	rt2x00_set_field32(&reg, TX_DMA_DST_CSR_DEST_AC3, 2);
+	rt2x00_set_field32(&reg, TX_DMA_DST_CSR_DEST_MGMT, 0);
+	rt2x00pci_register_write(rt2x00dev, TX_DMA_DST_CSR, reg);
+
+	rt2x00pci_register_read(rt2x00dev, LOAD_TX_RING_CSR, &reg);
+	rt2x00_set_field32(&reg, LOAD_TX_RING_CSR_LOAD_TXD_AC0, 1);
+	rt2x00_set_field32(&reg, LOAD_TX_RING_CSR_LOAD_TXD_AC1, 1);
+	rt2x00_set_field32(&reg, LOAD_TX_RING_CSR_LOAD_TXD_AC2, 1);
+	rt2x00_set_field32(&reg, LOAD_TX_RING_CSR_LOAD_TXD_AC3, 1);
+	rt2x00_set_field32(&reg, LOAD_TX_RING_CSR_LOAD_TXD_MGMT, 1);
+	rt2x00pci_register_write(rt2x00dev, LOAD_TX_RING_CSR, reg);
+
+	rt2x00pci_register_read(rt2x00dev, RX_CNTL_CSR, &reg);
+	rt2x00_set_field32(&reg, RX_CNTL_CSR_LOAD_RXD, 1);
+	rt2x00pci_register_write(rt2x00dev, RX_CNTL_CSR, reg);
 
 	return 0;
 }
@@ -1304,11 +1320,57 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev)
 	rt2x00_set_field32(&reg, TXRX_CSR0_TX_WITHOUT_WAITING, 0);
 	rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
 
-	rt2x00pci_register_write(rt2x00dev, TXRX_CSR1, 0x9eb39eb3);
-	rt2x00pci_register_write(rt2x00dev, TXRX_CSR2, 0x8a8b8c8d);
-	rt2x00pci_register_write(rt2x00dev, TXRX_CSR3, 0x00858687);
-	rt2x00pci_register_write(rt2x00dev, TXRX_CSR7, 0x2e31353b);
-	rt2x00pci_register_write(rt2x00dev, TXRX_CSR8, 0x2a2a2a2c);
+	rt2x00pci_register_read(rt2x00dev, TXRX_CSR1, &reg);
+	rt2x00_set_field32(&reg, TXRX_CSR1_BBP_ID0, 47); /* CCK Signal */
+	rt2x00_set_field32(&reg, TXRX_CSR1_BBP_ID0_VALID, 1);
+	rt2x00_set_field32(&reg, TXRX_CSR1_BBP_ID1, 30); /* Rssi */
+	rt2x00_set_field32(&reg, TXRX_CSR1_BBP_ID1_VALID, 1);
+	rt2x00_set_field32(&reg, TXRX_CSR1_BBP_ID2, 42); /* OFDM Rate */
+	rt2x00_set_field32(&reg, TXRX_CSR1_BBP_ID2_VALID, 1);
+	rt2x00_set_field32(&reg, TXRX_CSR1_BBP_ID3, 30); /* Rssi */
+	rt2x00_set_field32(&reg, TXRX_CSR1_BBP_ID3_VALID, 1);
+	rt2x00pci_register_write(rt2x00dev, TXRX_CSR1, reg);
+
+	/*
+	 * CCK TXD BBP registers
+	 */
+	rt2x00pci_register_read(rt2x00dev, TXRX_CSR2, &reg);
+	rt2x00_set_field32(&reg, TXRX_CSR2_BBP_ID0, 13);
+	rt2x00_set_field32(&reg, TXRX_CSR2_BBP_ID0_VALID, 1);
+	rt2x00_set_field32(&reg, TXRX_CSR2_BBP_ID1, 12);
+	rt2x00_set_field32(&reg, TXRX_CSR2_BBP_ID1_VALID, 1);
+	rt2x00_set_field32(&reg, TXRX_CSR2_BBP_ID2, 11);
+	rt2x00_set_field32(&reg, TXRX_CSR2_BBP_ID2_VALID, 1);
+	rt2x00_set_field32(&reg, TXRX_CSR2_BBP_ID3, 10);
+	rt2x00_set_field32(&reg, TXRX_CSR2_BBP_ID3_VALID, 1);
+	rt2x00pci_register_write(rt2x00dev, TXRX_CSR2, reg);
+
+	/*
+	 * OFDM TXD BBP registers
+	 */
+	rt2x00pci_register_read(rt2x00dev, TXRX_CSR3, &reg);
+	rt2x00_set_field32(&reg, TXRX_CSR3_BBP_ID0, 7);
+	rt2x00_set_field32(&reg, TXRX_CSR3_BBP_ID0_VALID, 1);
+	rt2x00_set_field32(&reg, TXRX_CSR3_BBP_ID1, 6);
+	rt2x00_set_field32(&reg, TXRX_CSR3_BBP_ID1_VALID, 1);
+	rt2x00_set_field32(&reg, TXRX_CSR3_BBP_ID2, 5);
+	rt2x00_set_field32(&reg, TXRX_CSR3_BBP_ID2_VALID, 1);
+	rt2x00pci_register_write(rt2x00dev, TXRX_CSR3, reg);
+
+	rt2x00pci_register_read(rt2x00dev, TXRX_CSR7, &reg);
+	rt2x00_set_field32(&reg, TXRX_CSR7_ACK_CTS_6MBS, 59);
+	rt2x00_set_field32(&reg, TXRX_CSR7_ACK_CTS_9MBS, 53);
+	rt2x00_set_field32(&reg, TXRX_CSR7_ACK_CTS_12MBS, 49);
+	rt2x00_set_field32(&reg, TXRX_CSR7_ACK_CTS_18MBS, 46);
+	rt2x00pci_register_write(rt2x00dev, TXRX_CSR7, reg);
+
+	rt2x00pci_register_read(rt2x00dev, TXRX_CSR8, &reg);
+	rt2x00_set_field32(&reg, TXRX_CSR8_ACK_CTS_24MBS, 44);
+	rt2x00_set_field32(&reg, TXRX_CSR8_ACK_CTS_36MBS, 42);
+	rt2x00_set_field32(&reg, TXRX_CSR8_ACK_CTS_48MBS, 42);
+	rt2x00_set_field32(&reg, TXRX_CSR8_ACK_CTS_54MBS, 42);
+	rt2x00pci_register_write(rt2x00dev, TXRX_CSR8, reg);
+
 	rt2x00pci_register_write(rt2x00dev, TXRX_CSR15, 0x0000000f);
 
 	rt2x00pci_register_write(rt2x00dev, MAC_CSR6, 0x00000fff);
@@ -1324,6 +1386,10 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev)
 
 	rt2x00pci_register_write(rt2x00dev, MAC_CSR13, 0x0000e000);
 
+	/*
+	 * Invalidate all Shared Keys (SEC_CSR0),
+	 * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5)
+	 */
 	rt2x00pci_register_write(rt2x00dev, SEC_CSR0, 0x00000000);
 	rt2x00pci_register_write(rt2x00dev, SEC_CSR1, 0x00000000);
 	rt2x00pci_register_write(rt2x00dev, SEC_CSR5, 0x00000000);
@@ -1496,6 +1562,8 @@ static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
 
 static int rt61pci_enable_radio(struct rt2x00_dev *rt2x00dev)
 {
+	u32 reg;
+
 	/*
 	 * Initialize all registers.
 	 */
@@ -1514,7 +1582,9 @@ static int rt61pci_enable_radio(struct rt2x00_dev *rt2x00dev)
 	/*
 	 * Enable RX.
 	 */
-	rt2x00pci_register_write(rt2x00dev, RX_CNTL_CSR, 0x00000001);
+	rt2x00pci_register_read(rt2x00dev, RX_CNTL_CSR, &reg);
+	rt2x00_set_field32(&reg, RX_CNTL_CSR_ENABLE_RX_DMA, 1);
+	rt2x00pci_register_write(rt2x00dev, RX_CNTL_CSR, reg);
 
 	/*
 	 * Enable LED
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h
index bd3e283..f24bff3 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.h
+++ b/drivers/net/wireless/rt2x00/rt61pci.h
@@ -399,16 +399,40 @@ struct hw_pairwise_ta_entry {
  * TXRX_CSR1
  */
 #define TXRX_CSR1			0x3044
+#define TXRX_CSR1_BBP_ID0		FIELD32(0x0000007f)
+#define TXRX_CSR1_BBP_ID0_VALID		FIELD32(0x00000080)
+#define TXRX_CSR1_BBP_ID1		FIELD32(0x00007f00)
+#define TXRX_CSR1_BBP_ID1_VALID		FIELD32(0x00008000)
+#define TXRX_CSR1_BBP_ID2		FIELD32(0x007f0000)
+#define TXRX_CSR1_BBP_ID2_VALID		FIELD32(0x00800000)
+#define TXRX_CSR1_BBP_ID3		FIELD32(0x7f000000)
+#define TXRX_CSR1_BBP_ID3_VALID		FIELD32(0x80000000)
 
 /*
  * TXRX_CSR2
  */
 #define TXRX_CSR2			0x3048
+#define TXRX_CSR2_BBP_ID0		FIELD32(0x0000007f)
+#define TXRX_CSR2_BBP_ID0_VALID		FIELD32(0x00000080)
+#define TXRX_CSR2_BBP_ID1		FIELD32(0x00007f00)
+#define TXRX_CSR2_BBP_ID1_VALID		FIELD32(0x00008000)
+#define TXRX_CSR2_BBP_ID2		FIELD32(0x007f0000)
+#define TXRX_CSR2_BBP_ID2_VALID		FIELD32(0x00800000)
+#define TXRX_CSR2_BBP_ID3		FIELD32(0x7f000000)
+#define TXRX_CSR2_BBP_ID3_VALID		FIELD32(0x80000000)
 
 /*
  * TXRX_CSR3
  */
 #define TXRX_CSR3			0x304c
+#define TXRX_CSR3_BBP_ID0		FIELD32(0x0000007f)
+#define TXRX_CSR3_BBP_ID0_VALID		FIELD32(0x00000080)
+#define TXRX_CSR3_BBP_ID1		FIELD32(0x00007f00)
+#define TXRX_CSR3_BBP_ID1_VALID		FIELD32(0x00008000)
+#define TXRX_CSR3_BBP_ID2		FIELD32(0x007f0000)
+#define TXRX_CSR3_BBP_ID2_VALID		FIELD32(0x00800000)
+#define TXRX_CSR3_BBP_ID3		FIELD32(0x7f000000)
+#define TXRX_CSR3_BBP_ID3_VALID		FIELD32(0x80000000)
 
 /*
  * TXRX_CSR4: Auto-Responder/Tx-retry register.
@@ -435,11 +459,27 @@ struct hw_pairwise_ta_entry {
 #define TXRX_CSR5			0x3054
 
 /*
- * ACK/CTS payload consumed time registers.
+ * TXRX_CSR6: ACK/CTS payload consumed time
  */
 #define TXRX_CSR6			0x3058
+
+/*
+ * TXRX_CSR7: OFDM ACK/CTS payload consumed time for 6/9/12/18 mbps.
+ */
 #define TXRX_CSR7			0x305c
+#define TXRX_CSR7_ACK_CTS_6MBS		FIELD32(0x000000ff)
+#define TXRX_CSR7_ACK_CTS_9MBS		FIELD32(0x0000ff00)
+#define TXRX_CSR7_ACK_CTS_12MBS		FIELD32(0x00ff0000)
+#define TXRX_CSR7_ACK_CTS_18MBS		FIELD32(0xff000000)
+
+/*
+ * TXRX_CSR8: OFDM ACK/CTS payload consumed time for 24/36/48/54 mbps.
+ */
 #define TXRX_CSR8			0x3060
+#define TXRX_CSR8_ACK_CTS_24MBS		FIELD32(0x000000ff)
+#define TXRX_CSR8_ACK_CTS_36MBS		FIELD32(0x0000ff00)
+#define TXRX_CSR8_ACK_CTS_48MBS		FIELD32(0x00ff0000)
+#define TXRX_CSR8_ACK_CTS_54MBS		FIELD32(0xff000000)
 
 /*
  * TXRX_CSR9: Synchronization control register.
@@ -542,11 +582,13 @@ struct hw_pairwise_ta_entry {
  * PHY_CSR5: RX to TX signal switch timing control.
  */
 #define PHY_CSR5			0x3094
+#define PHY_CSR5_IQ_FLIP		FIELD32(0x00000004)
 
 /*
  * PHY_CSR6: TX to RX signal timing control.
  */
 #define PHY_CSR6			0x3098
+#define PHY_CSR6_IQ_FLIP		FIELD32(0x00000004)
 
 /*
  * PHY_CSR7: TX DAC switching timing control.
@@ -561,6 +603,22 @@ struct hw_pairwise_ta_entry {
  * SEC_CSR0: Shared key table control.
  */
 #define SEC_CSR0			0x30a0
+#define SEC_CSR0_BSS0_KEY0_VALID	FIELD32(0x00000001)
+#define SEC_CSR0_BSS0_KEY1_VALID	FIELD32(0x00000002)
+#define SEC_CSR0_BSS0_KEY2_VALID	FIELD32(0x00000004)
+#define SEC_CSR0_BSS0_KEY3_VALID	FIELD32(0x00000008)
+#define SEC_CSR0_BSS1_KEY0_VALID	FIELD32(0x00000010)
+#define SEC_CSR0_BSS1_KEY1_VALID	FIELD32(0x00000020)
+#define SEC_CSR0_BSS1_KEY2_VALID	FIELD32(0x00000040)
+#define SEC_CSR0_BSS1_KEY3_VALID	FIELD32(0x00000080)
+#define SEC_CSR0_BSS2_KEY0_VALID	FIELD32(0x00000100)
+#define SEC_CSR0_BSS2_KEY1_VALID	FIELD32(0x00000200)
+#define SEC_CSR0_BSS2_KEY2_VALID	FIELD32(0x00000400)
+#define SEC_CSR0_BSS2_KEY3_VALID	FIELD32(0x00000800)
+#define SEC_CSR0_BSS3_KEY0_VALID	FIELD32(0x00001000)
+#define SEC_CSR0_BSS3_KEY1_VALID	FIELD32(0x00002000)
+#define SEC_CSR0_BSS3_KEY2_VALID	FIELD32(0x00004000)
+#define SEC_CSR0_BSS3_KEY3_VALID	FIELD32(0x00008000)
 
 /*
  * SEC_CSR1: Shared key table security mode register.
@@ -774,9 +832,15 @@ struct hw_pairwise_ta_entry {
 #define CWMAX_CSR_CWMAX3		FIELD32(0x0000f000)
 
 /*
- * TX_DMA_DST_CSR
+ * TX_DMA_DST_CSR: TX DMA destination
+ * 0: TX ring0, 1: TX ring1, 2: TX ring2 3: invalid
  */
 #define TX_DMA_DST_CSR			0x342c
+#define TX_DMA_DST_CSR_DEST_AC0		FIELD32(0x00000003)
+#define TX_DMA_DST_CSR_DEST_AC1		FIELD32(0x0000000c)
+#define TX_DMA_DST_CSR_DEST_AC2		FIELD32(0x00000030)
+#define TX_DMA_DST_CSR_DEST_AC3		FIELD32(0x000000c0)
+#define TX_DMA_DST_CSR_DEST_MGMT	FIELD32(0x00000300)
 
 /*
  * TX_CNTL_CSR: KICK/Abort TX.
@@ -802,9 +866,14 @@ struct hw_pairwise_ta_entry {
 #define TX_CNTL_CSR_ABORT_TX_MGMT	FIELD32(0x00100000)
 
 /*
- * LOAD_TX_RING_CSR
+ * LOAD_TX_RING_CSR: Load RX de
  */
 #define LOAD_TX_RING_CSR		0x3434
+#define LOAD_TX_RING_CSR_LOAD_TXD_AC0	FIELD32(0x00000001)
+#define LOAD_TX_RING_CSR_LOAD_TXD_AC1	FIELD32(0x00000002)
+#define LOAD_TX_RING_CSR_LOAD_TXD_AC2	FIELD32(0x00000004)
+#define LOAD_TX_RING_CSR_LOAD_TXD_AC3	FIELD32(0x00000008)
+#define LOAD_TX_RING_CSR_LOAD_TXD_MGMT	FIELD32(0x00000010)
 
 /*
  * Several read-only registers, for debugging.
@@ -834,6 +903,8 @@ struct hw_pairwise_ta_entry {
  * RX_CNTL_CSR
  */
 #define RX_CNTL_CSR			0x3458
+#define RX_CNTL_CSR_ENABLE_RX_DMA	FIELD32(0x00000001)
+#define RX_CNTL_CSR_LOAD_RXD		FIELD32(0x00000002)
 
 /*
  * RXPTR_CSR: Read-only, for debugging.
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 4aef5af..561e29b 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1003,11 +1003,57 @@ static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev)
 	rt2x00_set_field32(&reg, TXRX_CSR0_TX_WITHOUT_WAITING, 0);
 	rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg);
 
-	rt73usb_register_write(rt2x00dev, TXRX_CSR1, 0x9eaa9eaf);
-	rt73usb_register_write(rt2x00dev, TXRX_CSR2, 0x8a8b8c8d);
-	rt73usb_register_write(rt2x00dev, TXRX_CSR3, 0x00858687);
-	rt73usb_register_write(rt2x00dev, TXRX_CSR7, 0x2e31353b);
-	rt73usb_register_write(rt2x00dev, TXRX_CSR8, 0x2a2a2a2c);
+	rt73usb_register_read(rt2x00dev, TXRX_CSR1, &reg);
+	rt2x00_set_field32(&reg, TXRX_CSR1_BBP_ID0, 47); /* CCK Signal */
+	rt2x00_set_field32(&reg, TXRX_CSR1_BBP_ID0_VALID, 1);
+	rt2x00_set_field32(&reg, TXRX_CSR1_BBP_ID1, 30); /* Rssi */
+	rt2x00_set_field32(&reg, TXRX_CSR1_BBP_ID1_VALID, 1);
+	rt2x00_set_field32(&reg, TXRX_CSR1_BBP_ID2, 42); /* OFDM Rate */
+	rt2x00_set_field32(&reg, TXRX_CSR1_BBP_ID2_VALID, 1);
+	rt2x00_set_field32(&reg, TXRX_CSR1_BBP_ID3, 30); /* Rssi */
+	rt2x00_set_field32(&reg, TXRX_CSR1_BBP_ID3_VALID, 1);
+	rt73usb_register_write(rt2x00dev, TXRX_CSR1, reg);
+
+	/*
+	 * CCK TXD BBP registers
+	 */
+	rt73usb_register_read(rt2x00dev, TXRX_CSR2, &reg);
+	rt2x00_set_field32(&reg, TXRX_CSR2_BBP_ID0, 13);
+	rt2x00_set_field32(&reg, TXRX_CSR2_BBP_ID0_VALID, 1);
+	rt2x00_set_field32(&reg, TXRX_CSR2_BBP_ID1, 12);
+	rt2x00_set_field32(&reg, TXRX_CSR2_BBP_ID1_VALID, 1);
+	rt2x00_set_field32(&reg, TXRX_CSR2_BBP_ID2, 11);
+	rt2x00_set_field32(&reg, TXRX_CSR2_BBP_ID2_VALID, 1);
+	rt2x00_set_field32(&reg, TXRX_CSR2_BBP_ID3, 10);
+	rt2x00_set_field32(&reg, TXRX_CSR2_BBP_ID3_VALID, 1);
+	rt73usb_register_write(rt2x00dev, TXRX_CSR2, reg);
+
+	/*
+	 * OFDM TXD BBP registers
+	 */
+	rt73usb_register_read(rt2x00dev, TXRX_CSR3, &reg);
+	rt2x00_set_field32(&reg, TXRX_CSR3_BBP_ID0, 7);
+	rt2x00_set_field32(&reg, TXRX_CSR3_BBP_ID0_VALID, 1);
+	rt2x00_set_field32(&reg, TXRX_CSR3_BBP_ID1, 6);
+	rt2x00_set_field32(&reg, TXRX_CSR3_BBP_ID1_VALID, 1);
+	rt2x00_set_field32(&reg, TXRX_CSR3_BBP_ID2, 5);
+	rt2x00_set_field32(&reg, TXRX_CSR3_BBP_ID2_VALID, 1);
+	rt73usb_register_write(rt2x00dev, TXRX_CSR3, reg);
+
+	rt73usb_register_read(rt2x00dev, TXRX_CSR7, &reg);
+	rt2x00_set_field32(&reg, TXRX_CSR7_ACK_CTS_6MBS, 59);
+	rt2x00_set_field32(&reg, TXRX_CSR7_ACK_CTS_9MBS, 53);
+	rt2x00_set_field32(&reg, TXRX_CSR7_ACK_CTS_12MBS, 49);
+	rt2x00_set_field32(&reg, TXRX_CSR7_ACK_CTS_18MBS, 46);
+	rt73usb_register_write(rt2x00dev, TXRX_CSR7, reg);
+
+	rt73usb_register_read(rt2x00dev, TXRX_CSR8, &reg);
+	rt2x00_set_field32(&reg, TXRX_CSR8_ACK_CTS_24MBS, 44);
+	rt2x00_set_field32(&reg, TXRX_CSR8_ACK_CTS_36MBS, 42);
+	rt2x00_set_field32(&reg, TXRX_CSR8_ACK_CTS_48MBS, 42);
+	rt2x00_set_field32(&reg, TXRX_CSR8_ACK_CTS_54MBS, 42);
+	rt73usb_register_write(rt2x00dev, TXRX_CSR8, reg);
+
 	rt73usb_register_write(rt2x00dev, TXRX_CSR15, 0x0000000f);
 
 	rt73usb_register_read(rt2x00dev, MAC_CSR6, &reg);
@@ -1021,6 +1067,10 @@ static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev)
 
 	rt73usb_register_write(rt2x00dev, MAC_CSR13, 0x00007f00);
 
+	/*
+	 * Invalidate all Shared Keys (SEC_CSR0),
+	 * and clear the Shared key Cipher algorithms (SEC_CSR1 & SEC_CSR5)
+	 */
 	rt73usb_register_write(rt2x00dev, SEC_CSR0, 0x00000000);
 	rt73usb_register_write(rt2x00dev, SEC_CSR1, 0x00000000);
 	rt73usb_register_write(rt2x00dev, SEC_CSR5, 0x00000000);
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h
index 660a134..82f4e76 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.h
+++ b/drivers/net/wireless/rt2x00/rt73usb.h
@@ -298,16 +298,40 @@ struct hw_pairwise_ta_entry {
  * TXRX_CSR1
  */
 #define TXRX_CSR1			0x3044
+#define TXRX_CSR1_BBP_ID0		FIELD32(0x0000007f)
+#define TXRX_CSR1_BBP_ID0_VALID		FIELD32(0x00000080)
+#define TXRX_CSR1_BBP_ID1		FIELD32(0x00007f00)
+#define TXRX_CSR1_BBP_ID1_VALID		FIELD32(0x00008000)
+#define TXRX_CSR1_BBP_ID2		FIELD32(0x007f0000)
+#define TXRX_CSR1_BBP_ID2_VALID		FIELD32(0x00800000)
+#define TXRX_CSR1_BBP_ID3		FIELD32(0x7f000000)
+#define TXRX_CSR1_BBP_ID3_VALID		FIELD32(0x80000000)
 
 /*
  * TXRX_CSR2
  */
 #define TXRX_CSR2			0x3048
+#define TXRX_CSR2_BBP_ID0		FIELD32(0x0000007f)
+#define TXRX_CSR2_BBP_ID0_VALID		FIELD32(0x00000080)
+#define TXRX_CSR2_BBP_ID1		FIELD32(0x00007f00)
+#define TXRX_CSR2_BBP_ID1_VALID		FIELD32(0x00008000)
+#define TXRX_CSR2_BBP_ID2		FIELD32(0x007f0000)
+#define TXRX_CSR2_BBP_ID2_VALID		FIELD32(0x00800000)
+#define TXRX_CSR2_BBP_ID3		FIELD32(0x7f000000)
+#define TXRX_CSR2_BBP_ID3_VALID		FIELD32(0x80000000)
 
 /*
  * TXRX_CSR3
  */
 #define TXRX_CSR3			0x304c
+#define TXRX_CSR3_BBP_ID0		FIELD32(0x0000007f)
+#define TXRX_CSR3_BBP_ID0_VALID		FIELD32(0x00000080)
+#define TXRX_CSR3_BBP_ID1		FIELD32(0x00007f00)
+#define TXRX_CSR3_BBP_ID1_VALID		FIELD32(0x00008000)
+#define TXRX_CSR3_BBP_ID2		FIELD32(0x007f0000)
+#define TXRX_CSR3_BBP_ID2_VALID		FIELD32(0x00800000)
+#define TXRX_CSR3_BBP_ID3		FIELD32(0x7f000000)
+#define TXRX_CSR3_BBP_ID3_VALID		FIELD32(0x80000000)
 
 /*
  * TXRX_CSR4: Auto-Responder/Tx-retry register.
@@ -334,11 +358,27 @@ struct hw_pairwise_ta_entry {
 #define TXRX_CSR5			0x3054
 
 /*
- * ACK/CTS payload consumed time registers.
+ * TXRX_CSR6: ACK/CTS payload consumed time
  */
 #define TXRX_CSR6			0x3058
+
+/*
+ * TXRX_CSR7: OFDM ACK/CTS payload consumed time for 6/9/12/18 mbps.
+ */
 #define TXRX_CSR7			0x305c
+#define TXRX_CSR7_ACK_CTS_6MBS		FIELD32(0x000000ff)
+#define TXRX_CSR7_ACK_CTS_9MBS		FIELD32(0x0000ff00)
+#define TXRX_CSR7_ACK_CTS_12MBS		FIELD32(0x00ff0000)
+#define TXRX_CSR7_ACK_CTS_18MBS		FIELD32(0xff000000)
+
+/*
+ * TXRX_CSR8: OFDM ACK/CTS payload consumed time for 24/36/48/54 mbps.
+ */
 #define TXRX_CSR8			0x3060
+#define TXRX_CSR8_ACK_CTS_24MBS		FIELD32(0x000000ff)
+#define TXRX_CSR8_ACK_CTS_36MBS		FIELD32(0x0000ff00)
+#define TXRX_CSR8_ACK_CTS_48MBS		FIELD32(0x00ff0000)
+#define TXRX_CSR8_ACK_CTS_54MBS		FIELD32(0xff000000)
 
 /*
  * TXRX_CSR9: Synchronization control register.
@@ -442,11 +482,13 @@ struct hw_pairwise_ta_entry {
  * PHY_CSR5: RX to TX signal switch timing control.
  */
 #define PHY_CSR5			0x3094
+#define PHY_CSR5_IQ_FLIP		FIELD32(0x00000004)
 
 /*
  * PHY_CSR6: TX to RX signal timing control.
  */
 #define PHY_CSR6			0x3098
+#define PHY_CSR6_IQ_FLIP		FIELD32(0x00000004)
 
 /*
  * PHY_CSR7: TX DAC switching timing control.
@@ -461,6 +503,22 @@ struct hw_pairwise_ta_entry {
  * SEC_CSR0: Shared key table control.
  */
 #define SEC_CSR0			0x30a0
+#define SEC_CSR0_BSS0_KEY0_VALID	FIELD32(0x00000001)
+#define SEC_CSR0_BSS0_KEY1_VALID	FIELD32(0x00000002)
+#define SEC_CSR0_BSS0_KEY2_VALID	FIELD32(0x00000004)
+#define SEC_CSR0_BSS0_KEY3_VALID	FIELD32(0x00000008)
+#define SEC_CSR0_BSS1_KEY0_VALID	FIELD32(0x00000010)
+#define SEC_CSR0_BSS1_KEY1_VALID	FIELD32(0x00000020)
+#define SEC_CSR0_BSS1_KEY2_VALID	FIELD32(0x00000040)
+#define SEC_CSR0_BSS1_KEY3_VALID	FIELD32(0x00000080)
+#define SEC_CSR0_BSS2_KEY0_VALID	FIELD32(0x00000100)
+#define SEC_CSR0_BSS2_KEY1_VALID	FIELD32(0x00000200)
+#define SEC_CSR0_BSS2_KEY2_VALID	FIELD32(0x00000400)
+#define SEC_CSR0_BSS2_KEY3_VALID	FIELD32(0x00000800)
+#define SEC_CSR0_BSS3_KEY0_VALID	FIELD32(0x00001000)
+#define SEC_CSR0_BSS3_KEY1_VALID	FIELD32(0x00002000)
+#define SEC_CSR0_BSS3_KEY2_VALID	FIELD32(0x00004000)
+#define SEC_CSR0_BSS3_KEY3_VALID	FIELD32(0x00008000)
 
 /*
  * SEC_CSR1: Shared key table security mode register.
-- 
1.5.3

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

* [PATCH 14/24] rt2x00: New USB ID's for rt73usb and rt2500usb
       [not found] <200709161403.11332.IvDoorn@gmail.com>
                   ` (12 preceding siblings ...)
  2007-09-16 12:18 ` [PATCH 13/24] rt2x00: Reduce magic value writing to device Ivo van Doorn
@ 2007-09-16 12:19 ` Ivo van Doorn
  2007-09-16 12:19 ` [PATCH 15/24] rt2x00: Beacon ring entries should have QID_MGMT Ivo van Doorn
                   ` (9 subsequent siblings)
  23 siblings, 0 replies; 24+ messages in thread
From: Ivo van Doorn @ 2007-09-16 12:19 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, rt2400-devel

Add several new USB id's for the rt73usb driver
and add a single new USB id for the rt2500usb driver.

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

diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 2c2d8b7..5bdf64f 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1783,6 +1783,8 @@ static struct usb_device_id rt2500usb_device_table[] = {
 	{ USB_DEVICE(0x0411, 0x0066), USB_DEVICE_DATA(&rt2500usb_ops) },
 	{ USB_DEVICE(0x0411, 0x0067), USB_DEVICE_DATA(&rt2500usb_ops) },
 	{ USB_DEVICE(0x0411, 0x008b), USB_DEVICE_DATA(&rt2500usb_ops) },
+	{ USB_DEVICE(0x0411, 0x0097), USB_DEVICE_DATA(&rt2500usb_ops) },
+
 	/* MSI */
 	{ USB_DEVICE(0x0db0, 0x6861), USB_DEVICE_DATA(&rt2500usb_ops) },
 	{ USB_DEVICE(0x0db0, 0x6865), USB_DEVICE_DATA(&rt2500usb_ops) },
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 561e29b..67a6644 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2080,6 +2080,7 @@ static struct usb_device_id rt73usb_device_table[] = {
 	{ USB_DEVICE(0x13b1, 0x0023), USB_DEVICE_DATA(&rt73usb_ops) },
 	/* MSI */
 	{ USB_DEVICE(0x0db0, 0x6877), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x0db0, 0x6874), USB_DEVICE_DATA(&rt73usb_ops) },
 	{ USB_DEVICE(0x0db0, 0xa861), USB_DEVICE_DATA(&rt73usb_ops) },
 	{ USB_DEVICE(0x0db0, 0xa874), USB_DEVICE_DATA(&rt73usb_ops) },
 	/* Ralink */
@@ -2088,6 +2089,9 @@ static struct usb_device_id rt73usb_device_table[] = {
 	/* Qcom */
 	{ USB_DEVICE(0x18e8, 0x6196), USB_DEVICE_DATA(&rt73usb_ops) },
 	{ USB_DEVICE(0x18e8, 0x6229), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x18e8, 0x6238), USB_DEVICE_DATA(&rt73usb_ops) },
+	/* Senao */
+	{ USB_DEVICE(0x1740, 0x7100), USB_DEVICE_DATA(&rt73usb_ops) },
 	/* Sitecom */
 	{ USB_DEVICE(0x0df6, 0x9712), USB_DEVICE_DATA(&rt73usb_ops) },
 	{ USB_DEVICE(0x0df6, 0x90ac), USB_DEVICE_DATA(&rt73usb_ops) },
-- 
1.5.3

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

* [PATCH 15/24] rt2x00: Beacon ring entries should have QID_MGMT
       [not found] <200709161403.11332.IvDoorn@gmail.com>
                   ` (13 preceding siblings ...)
  2007-09-16 12:19 ` [PATCH 14/24] rt2x00: New USB ID's for rt73usb and rt2500usb Ivo van Doorn
@ 2007-09-16 12:19 ` Ivo van Doorn
  2007-09-16 12:19 ` [PATCH 16/24] rt2x00: Fix DEV_RATEBIT_ definitions Ivo van Doorn
                   ` (8 subsequent siblings)
  23 siblings, 0 replies; 24+ messages in thread
From: Ivo van Doorn @ 2007-09-16 12:19 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, rt2400-devel

Put the QID values into a define, and make sure
that Beacon and ATIM rings are assigned a value of
13 (QID_MGMT) instead of 15 (QID_OTHER)

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2x00dev.c  |    5 ++++-
 drivers/net/wireless/rt2x00/rt2x00ring.h |    6 ++++++
 2 files changed, 10 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 7730d9d..6992727 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -422,8 +422,11 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
 	 */
 	if (control->queue < rt2x00dev->hw->queues)
 		desc.queue = control->queue;
+	else if (control->queue == IEEE80211_TX_QUEUE_BEACON ||
+		 control->queue == IEEE80211_TX_QUEUE_AFTER_BEACON)
+		desc.queue = QUEUE_MGMT;
 	else
-		desc.queue = 15;
+		desc.queue = QUEUE_OTHER;
 
 	/*
 	 * Read required fields from ieee80211 header.
diff --git a/drivers/net/wireless/rt2x00/rt2x00ring.h b/drivers/net/wireless/rt2x00/rt2x00ring.h
index 78e128a..122c752 100644
--- a/drivers/net/wireless/rt2x00/rt2x00ring.h
+++ b/drivers/net/wireless/rt2x00/rt2x00ring.h
@@ -54,7 +54,13 @@ struct data_entry_desc {
 #define ENTRY_TXD_REQ_TIMESTAMP	5
 #define ENTRY_TXD_BURST		6
 
+/*
+ * Queue ID. ID's 0-4 are data TX rings
+ */
 	int queue;
+#define QUEUE_MGMT		13
+#define QUEUE_RX		14
+#define QUEUE_OTHER		15
 
 	/*
 	 * PLCP values.
-- 
1.5.3

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

* [PATCH 16/24] rt2x00: Fix DEV_RATEBIT_ definitions
       [not found] <200709161403.11332.IvDoorn@gmail.com>
                   ` (14 preceding siblings ...)
  2007-09-16 12:19 ` [PATCH 15/24] rt2x00: Beacon ring entries should have QID_MGMT Ivo van Doorn
@ 2007-09-16 12:19 ` Ivo van Doorn
  2007-09-16 12:19 ` [PATCH 17/24] rt2x00: Fix rfkill handling Ivo van Doorn
                   ` (7 subsequent siblings)
  23 siblings, 0 replies; 24+ messages in thread
From: Ivo van Doorn @ 2007-09-16 12:19 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, rt2400-devel

The DEV_RATEBIT_ were all shifted 1 bit too much,
this caused the RATEMASK to overflow.

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2x00reg.h |   24 ++++++++++++------------
 1 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h
index 5e7b63e..7927d5f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00reg.h
+++ b/drivers/net/wireless/rt2x00/rt2x00reg.h
@@ -231,18 +231,18 @@ static inline u8 rt2x00_get_field8(const u8 reg,
 /*
  * Bitfields
  */
-#define DEV_RATEBIT_1MB		( 1 << 1 )
-#define DEV_RATEBIT_2MB		( 1 << 2 )
-#define DEV_RATEBIT_5_5MB	( 1 << 3 )
-#define DEV_RATEBIT_11MB	( 1 << 4 )
-#define DEV_RATEBIT_6MB		( 1 << 5 )
-#define DEV_RATEBIT_9MB		( 1 << 6 )
-#define DEV_RATEBIT_12MB	( 1 << 7 )
-#define DEV_RATEBIT_18MB	( 1 << 8 )
-#define DEV_RATEBIT_24MB	( 1 << 9 )
-#define DEV_RATEBIT_36MB	( 1 << 10 )
-#define DEV_RATEBIT_48MB	( 1 << 11 )
-#define DEV_RATEBIT_54MB	( 1 << 12 )
+#define DEV_RATEBIT_1MB		( 1 << 0 )
+#define DEV_RATEBIT_2MB		( 1 << 1 )
+#define DEV_RATEBIT_5_5MB	( 1 << 2 )
+#define DEV_RATEBIT_11MB	( 1 << 3 )
+#define DEV_RATEBIT_6MB		( 1 << 4 )
+#define DEV_RATEBIT_9MB		( 1 << 5 )
+#define DEV_RATEBIT_12MB	( 1 << 6 )
+#define DEV_RATEBIT_18MB	( 1 << 7 )
+#define DEV_RATEBIT_24MB	( 1 << 8 )
+#define DEV_RATEBIT_36MB	( 1 << 9 )
+#define DEV_RATEBIT_48MB	( 1 << 10 )
+#define DEV_RATEBIT_54MB	( 1 << 11 )
 
 /*
  * Bitmasks for DEV_RATEMASK
-- 
1.5.3

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

* [PATCH 17/24] rt2x00: Fix rfkill handling
       [not found] <200709161403.11332.IvDoorn@gmail.com>
                   ` (15 preceding siblings ...)
  2007-09-16 12:19 ` [PATCH 16/24] rt2x00: Fix DEV_RATEBIT_ definitions Ivo van Doorn
@ 2007-09-16 12:19 ` Ivo van Doorn
  2007-09-16 12:19 ` [PATCH 18/24] rt2x00: Merge allocation/free register components Ivo van Doorn
                   ` (6 subsequent siblings)
  23 siblings, 0 replies; 24+ messages in thread
From: Ivo van Doorn @ 2007-09-16 12:19 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, rt2400-devel

When the rfkill key has been pressed rt2x00 should send out an rfkill
event instead of toggling all keys. This will make sure the event
will go through all correct rfkill layers.

Also initialize the rfkill->state field to make sure we correctly
notice key changes.

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2x00rfkill.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
index 7dde53c..dc5b696 100644
--- a/drivers/net/wireless/rt2x00/rt2x00rfkill.c
+++ b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
@@ -68,9 +68,10 @@ static int rt2x00rfkill_toggle_radio(void *data, enum rfkill_state state)
 static void rt2x00rfkill_poll(struct input_polled_dev *poll_dev)
 {
 	struct rt2x00_dev *rt2x00dev = poll_dev->private;
-	int status = rt2x00dev->ops->lib->rfkill_poll(rt2x00dev);
+	int state = rt2x00dev->ops->lib->rfkill_poll(rt2x00dev);
 
-	rfkill_switch_all(rt2x00dev->rfkill->type, status);
+	if (rt2x00dev->rfkill->state != state)
+		input_report_key(poll_dev->input, KEY_WLAN, 1);
 }
 
 int rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
@@ -120,6 +121,7 @@ int rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
 
 	rt2x00dev->rfkill->name = rt2x00dev->ops->name;
 	rt2x00dev->rfkill->data = rt2x00dev;
+	rt2x00dev->rfkill->state = rt2x00dev->ops->lib->rfkill_poll(rt2x00dev);
 	rt2x00dev->rfkill->toggle_radio = rt2x00rfkill_toggle_radio;
 
 	rt2x00dev->poll_dev = input_allocate_polled_device();
-- 
1.5.3

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

* [PATCH 18/24] rt2x00: Merge allocation/free register components
       [not found] <200709161403.11332.IvDoorn@gmail.com>
                   ` (16 preceding siblings ...)
  2007-09-16 12:19 ` [PATCH 17/24] rt2x00: Fix rfkill handling Ivo van Doorn
@ 2007-09-16 12:19 ` Ivo van Doorn
  2007-09-16 12:19 ` [PATCH 19/24] rt2x00: macro's shouldn't use hidden arguments Ivo van Doorn
                   ` (5 subsequent siblings)
  23 siblings, 0 replies; 24+ messages in thread
From: Ivo van Doorn @ 2007-09-16 12:19 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, rt2400-devel

The csr, eeprom and rf register components are always
allocated and freed at the same locations.
It will be easier if the 3 allocation and the 3 free functions
are merged into a single allocation and single free function
which can be used everywhere.

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2x00pci.c |  105 +++++++++----------------------
 drivers/net/wireless/rt2x00/rt2x00usb.c |   97 ++++++++--------------------
 2 files changed, 59 insertions(+), 143 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index f61cc7f..85629f1 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -286,56 +286,45 @@ EXPORT_SYMBOL_GPL(rt2x00pci_uninitialize);
 /*
  * PCI driver handlers.
  */
-static int rt2x00pci_alloc_csr(struct rt2x00_dev *rt2x00dev)
+static void rt2x00pci_free_reg(struct rt2x00_dev *rt2x00dev)
 {
-	struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev);
-
-	rt2x00dev->csr_addr = ioremap(pci_resource_start(pci_dev, 0),
-				      pci_resource_len(pci_dev, 0));
-	if (!rt2x00dev->csr_addr) {
-		ERROR(rt2x00dev, "Ioremap failed.\n");
-		return -ENOMEM;
-	}
+	kfree(rt2x00dev->rf);
+	rt2x00dev->rf = NULL;
 
-	return 0;
-}
+	kfree(rt2x00dev->eeprom);
+	rt2x00dev->eeprom = NULL;
 
-static void rt2x00pci_free_csr(struct rt2x00_dev *rt2x00dev)
-{
 	if (rt2x00dev->csr_addr) {
 		iounmap(rt2x00dev->csr_addr);
 		rt2x00dev->csr_addr = NULL;
 	}
 }
 
-static int rt2x00pci_alloc_eeprom(struct rt2x00_dev *rt2x00dev)
+static int rt2x00pci_alloc_reg(struct rt2x00_dev *rt2x00dev)
 {
-	rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL);
-	if (!rt2x00dev->eeprom)
-		return -ENOMEM;
+	struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev);
 
-	return 0;
-}
+	rt2x00dev->csr_addr = ioremap(pci_resource_start(pci_dev, 0),
+				      pci_resource_len(pci_dev, 0));
+	if (!rt2x00dev->csr_addr)
+		goto exit;
 
-static void rt2x00pci_free_eeprom(struct rt2x00_dev *rt2x00dev)
-{
-	kfree(rt2x00dev->eeprom);
-	rt2x00dev->eeprom = NULL;
-}
+	rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL);
+	if (!rt2x00dev->eeprom)
+		goto exit;
 
-static int rt2x00pci_alloc_rf(struct rt2x00_dev *rt2x00dev)
-{
 	rt2x00dev->rf = kzalloc(rt2x00dev->ops->rf_size, GFP_KERNEL);
 	if (!rt2x00dev->rf)
-		return -ENOMEM;
+		goto exit;
 
 	return 0;
-}
 
-static void rt2x00pci_free_rf(struct rt2x00_dev *rt2x00dev)
-{
-	kfree(rt2x00dev->rf);
-	rt2x00dev->rf = NULL;
+exit:
+	ERROR_PROBE("Failed to allocate registers.\n");
+
+	rt2x00pci_free_reg(rt2x00dev);
+
+	return -ENOMEM;
 }
 
 int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
@@ -383,32 +372,18 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
 	rt2x00dev->ops = ops;
 	rt2x00dev->hw = hw;
 
-	retval = rt2x00pci_alloc_csr(rt2x00dev);
+	retval = rt2x00pci_alloc_reg(rt2x00dev);
 	if (retval)
 		goto exit_free_device;
 
-	retval = rt2x00pci_alloc_eeprom(rt2x00dev);
-	if (retval)
-		goto exit_free_csr;
-
-	retval = rt2x00pci_alloc_rf(rt2x00dev);
-	if (retval)
-		goto exit_free_eeprom;
-
 	retval = rt2x00lib_probe_dev(rt2x00dev);
 	if (retval)
-		goto exit_free_rf;
+		goto exit_free_reg;
 
 	return 0;
 
-exit_free_rf:
-	rt2x00pci_free_rf(rt2x00dev);
-
-exit_free_eeprom:
-	rt2x00pci_free_eeprom(rt2x00dev);
-
-exit_free_csr:
-	rt2x00pci_free_csr(rt2x00dev);
+exit_free_reg:
+	rt2x00pci_free_reg(rt2x00dev);
 
 exit_free_device:
 	ieee80211_free_hw(hw);
@@ -435,9 +410,7 @@ void rt2x00pci_remove(struct pci_dev *pci_dev)
 	 * Free all allocated data.
 	 */
 	rt2x00lib_remove_dev(rt2x00dev);
-	rt2x00pci_free_rf(rt2x00dev);
-	rt2x00pci_free_eeprom(rt2x00dev);
-	rt2x00pci_free_csr(rt2x00dev);
+	rt2x00pci_free_reg(rt2x00dev);
 	ieee80211_free_hw(hw);
 
 	/*
@@ -460,9 +433,7 @@ int rt2x00pci_suspend(struct pci_dev *pci_dev, pm_message_t state)
 	if (retval)
 		return retval;
 
-	rt2x00pci_free_rf(rt2x00dev);
-	rt2x00pci_free_eeprom(rt2x00dev);
-	rt2x00pci_free_csr(rt2x00dev);
+	rt2x00pci_free_reg(rt2x00dev);
 
 	pci_save_state(pci_dev);
 	pci_disable_device(pci_dev);
@@ -483,32 +454,18 @@ int rt2x00pci_resume(struct pci_dev *pci_dev)
 		return -EIO;
 	}
 
-	retval = rt2x00pci_alloc_csr(rt2x00dev);
+	retval = rt2x00pci_alloc_reg(rt2x00dev);
 	if (retval)
 		return retval;
 
-	retval = rt2x00pci_alloc_eeprom(rt2x00dev);
-	if (retval)
-		goto exit_free_csr;
-
-	retval = rt2x00pci_alloc_rf(rt2x00dev);
-	if (retval)
-		goto exit_free_eeprom;
-
 	retval = rt2x00lib_resume(rt2x00dev);
 	if (retval)
-		goto exit_free_rf;
+		goto exit_free_reg;
 
 	return 0;
 
-exit_free_rf:
-	rt2x00pci_free_rf(rt2x00dev);
-
-exit_free_eeprom:
-	rt2x00pci_free_eeprom(rt2x00dev);
-
-exit_free_csr:
-	rt2x00pci_free_csr(rt2x00dev);
+exit_free_reg:
+	rt2x00pci_free_reg(rt2x00dev);
 
 	return retval;
 }
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index ede3766..a0f05ca 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -432,49 +432,40 @@ EXPORT_SYMBOL_GPL(rt2x00usb_uninitialize);
 /*
  * USB driver handlers.
  */
-static int rt2x00usb_alloc_csr(struct rt2x00_dev *rt2x00dev)
+static void rt2x00usb_free_reg(struct rt2x00_dev *rt2x00dev)
 {
-	rt2x00dev->csr_cache = kzalloc(CSR_CACHE_SIZE, GFP_KERNEL);
-	if (!rt2x00dev->csr_cache)
-		return -ENOMEM;
+	kfree(rt2x00dev->rf);
+	rt2x00dev->rf = NULL;
 
-	return 0;
-}
+	kfree(rt2x00dev->eeprom);
+	rt2x00dev->eeprom = NULL;
 
-static void rt2x00usb_free_csr(struct rt2x00_dev *rt2x00dev)
-{
 	kfree(rt2x00dev->csr_cache);
 	rt2x00dev->csr_cache = NULL;
 }
 
-static int rt2x00usb_alloc_eeprom(struct rt2x00_dev *rt2x00dev)
+static int rt2x00usb_alloc_reg(struct rt2x00_dev *rt2x00dev)
 {
+	rt2x00dev->csr_cache = kzalloc(CSR_CACHE_SIZE, GFP_KERNEL);
+	if (!rt2x00dev->csr_cache)
+		goto exit;
+
 	rt2x00dev->eeprom = kzalloc(rt2x00dev->ops->eeprom_size, GFP_KERNEL);
 	if (!rt2x00dev->eeprom)
-		return -ENOMEM;
-
-	return 0;
-}
-
-static void rt2x00usb_free_eeprom(struct rt2x00_dev *rt2x00dev)
-{
-	kfree(rt2x00dev->eeprom);
-	rt2x00dev->eeprom = NULL;
-}
+		goto exit;
 
-static int rt2x00usb_alloc_rf(struct rt2x00_dev *rt2x00dev)
-{
 	rt2x00dev->rf = kzalloc(rt2x00dev->ops->rf_size, GFP_KERNEL);
 	if (!rt2x00dev->rf)
-		return -ENOMEM;
+		goto exit;
 
 	return 0;
-}
 
-static void rt2x00usb_free_rf(struct rt2x00_dev *rt2x00dev)
-{
-	kfree(rt2x00dev->rf);
-	rt2x00dev->rf = NULL;
+exit:
+	ERROR_PROBE("Failed to allocate registers.\n");
+
+	rt2x00usb_free_reg(rt2x00dev);
+
+	return -ENOMEM;
 }
 
 int rt2x00usb_probe(struct usb_interface *usb_intf,
@@ -502,32 +493,18 @@ int rt2x00usb_probe(struct usb_interface *usb_intf,
 	rt2x00dev->ops = ops;
 	rt2x00dev->hw = hw;
 
-	retval = rt2x00usb_alloc_csr(rt2x00dev);
+	retval = rt2x00usb_alloc_reg(rt2x00dev);
 	if (retval)
 		goto exit_free_device;
 
-	retval = rt2x00usb_alloc_eeprom(rt2x00dev);
-	if (retval)
-		goto exit_free_cr;
-
-	retval = rt2x00usb_alloc_rf(rt2x00dev);
-	if (retval)
-		goto exit_free_eeprom;
-
 	retval = rt2x00lib_probe_dev(rt2x00dev);
 	if (retval)
-		goto exit_free_rf;
+		goto exit_free_reg;
 
 	return 0;
 
-exit_free_rf:
-	rt2x00usb_free_rf(rt2x00dev);
-
-exit_free_eeprom:
-	rt2x00usb_free_eeprom(rt2x00dev);
-
-exit_free_cr:
-	rt2x00usb_free_csr(rt2x00dev);
+exit_free_reg:
+	rt2x00usb_free_reg(rt2x00dev);
 
 exit_free_device:
 	ieee80211_free_hw(hw);
@@ -550,9 +527,7 @@ void rt2x00usb_disconnect(struct usb_interface *usb_intf)
 	 * Free all allocated data.
 	 */
 	rt2x00lib_remove_dev(rt2x00dev);
-	rt2x00usb_free_rf(rt2x00dev);
-	rt2x00usb_free_eeprom(rt2x00dev);
-	rt2x00usb_free_csr(rt2x00dev);
+	rt2x00usb_free_reg(rt2x00dev);
 	ieee80211_free_hw(hw);
 
 	/*
@@ -574,9 +549,7 @@ int rt2x00usb_suspend(struct usb_interface *usb_intf, pm_message_t state)
 	if (retval)
 		return retval;
 
-	rt2x00usb_free_rf(rt2x00dev);
-	rt2x00usb_free_eeprom(rt2x00dev);
-	rt2x00usb_free_csr(rt2x00dev);
+	rt2x00usb_free_reg(rt2x00dev);
 
 	/*
 	 * Decrease usbdev refcount.
@@ -595,32 +568,18 @@ int rt2x00usb_resume(struct usb_interface *usb_intf)
 
 	usb_get_dev(interface_to_usbdev(usb_intf));
 
-	retval = rt2x00usb_alloc_csr(rt2x00dev);
+	retval = rt2x00usb_alloc_reg(rt2x00dev);
 	if (retval)
 		return retval;
 
-	retval = rt2x00usb_alloc_eeprom(rt2x00dev);
-	if (retval)
-		goto exit_free_csr;
-
-	retval = rt2x00usb_alloc_rf(rt2x00dev);
-	if (retval)
-		goto exit_free_eeprom;
-
 	retval = rt2x00lib_resume(rt2x00dev);
 	if (retval)
-		goto exit_free_rf;
+		goto exit_free_reg;
 
 	return 0;
 
-exit_free_rf:
-	rt2x00usb_free_rf(rt2x00dev);
-
-exit_free_eeprom:
-	rt2x00usb_free_eeprom(rt2x00dev);
-
-exit_free_csr:
-	rt2x00usb_free_csr(rt2x00dev);
+exit_free_reg:
+	rt2x00usb_free_reg(rt2x00dev);
 
 	return retval;
 }
-- 
1.5.3


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

* [PATCH 19/24] rt2x00: macro's shouldn't use hidden arguments
       [not found] <200709161403.11332.IvDoorn@gmail.com>
                   ` (17 preceding siblings ...)
  2007-09-16 12:19 ` [PATCH 18/24] rt2x00: Merge allocation/free register components Ivo van Doorn
@ 2007-09-16 12:19 ` Ivo van Doorn
  2007-09-16 12:19 ` [PATCH 20/24] rt2x00: Fix channel initialization Ivo van Doorn
                   ` (4 subsequent siblings)
  23 siblings, 0 replies; 24+ messages in thread
From: Ivo van Doorn @ 2007-09-16 12:19 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, rt2400-devel

RT2X00DEBUGFS_CREATE_ENTRY used the intf variable
while this wasn't passed as argument. That can be
considered as a bad coding style.

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2x00debug.c |   26 +++++++++++++-------------
 1 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index eaa4c54..4d2aaec 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -270,29 +270,29 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
 	if (IS_ERR(intf->chipset_entry))
 		goto exit;
 
-#define RT2X00DEBUGFS_CREATE_ENTRY(__name)			\
+#define RT2X00DEBUGFS_CREATE_ENTRY(__intf, __name)		\
 ({								\
-	intf->__name##_off_entry =				\
+	(__intf)->__name##_off_entry =				\
 	    debugfs_create_u32(__stringify(__name) "_offset",	\
 			       S_IRUGO | S_IWUSR,		\
-			       intf->driver_folder,		\
-			       &intf->offset_##__name);		\
-	if (IS_ERR(intf->__name##_off_entry))			\
+			       (__intf)->driver_folder,		\
+			       &(__intf)->offset_##__name);	\
+	if (IS_ERR((__intf)->__name##_off_entry))		\
 		goto exit;					\
 								\
-	intf->__name##_val_entry =				\
+	(__intf)->__name##_val_entry =				\
 	    debugfs_create_file(__stringify(__name) "_value",	\
 				S_IRUGO | S_IWUSR,		\
-				intf->driver_folder,		\
-				intf, &rt2x00debug_fop_##__name);\
-	if (IS_ERR(intf->__name##_val_entry))			\
+				(__intf)->driver_folder,	\
+				(__intf), &rt2x00debug_fop_##__name);\
+	if (IS_ERR((__intf)->__name##_val_entry))		\
 		goto exit;					\
 })
 
-	RT2X00DEBUGFS_CREATE_ENTRY(csr);
-	RT2X00DEBUGFS_CREATE_ENTRY(eeprom);
-	RT2X00DEBUGFS_CREATE_ENTRY(bbp);
-	RT2X00DEBUGFS_CREATE_ENTRY(rf);
+	RT2X00DEBUGFS_CREATE_ENTRY(intf, csr);
+	RT2X00DEBUGFS_CREATE_ENTRY(intf, eeprom);
+	RT2X00DEBUGFS_CREATE_ENTRY(intf, bbp);
+	RT2X00DEBUGFS_CREATE_ENTRY(intf, rf);
 
 #undef RT2X00DEBUGFS_CREATE_ENTRY
 
-- 
1.5.3

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

* [PATCH 20/24] rt2x00: Fix channel initialization
       [not found] <200709161403.11332.IvDoorn@gmail.com>
                   ` (18 preceding siblings ...)
  2007-09-16 12:19 ` [PATCH 19/24] rt2x00: macro's shouldn't use hidden arguments Ivo van Doorn
@ 2007-09-16 12:19 ` Ivo van Doorn
  2007-09-16 12:19 ` [PATCH 21/24] rt2x00: Add better CONFIG_PM checks Ivo van Doorn
                   ` (3 subsequent siblings)
  23 siblings, 0 replies; 24+ messages in thread
From: Ivo van Doorn @ 2007-09-16 12:19 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, rt2400-devel

Move the channel locking code of rt61 and rt73 into a seperate
function since both config_channel and config_txpower have exactly
the same code.

Use the BBP_R3_SMART_MODE define when we are working with the
BBP R3 register. Also optimize the code by removing the if-statement.

The BBP R94 must be initialized during the channel setup as well,
the value depends on the txpower.

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
 drivers/net/wireless/rt2x00/rt61pci.c |  104 +++++++++++++++------------------
 drivers/net/wireless/rt2x00/rt73usb.c |  104 +++++++++++++++------------------
 2 files changed, 94 insertions(+), 114 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index a2d852f..6baa651 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -452,58 +452,67 @@ static void rt61pci_config_phymode(struct rt2x00_dev *rt2x00dev,
 	rt61pci_config_rate(rt2x00dev, rate->val2);
 }
 
-static void rt61pci_config_channel(struct rt2x00_dev *rt2x00dev,
-				   const int index, const int channel,
-				   const int txpower)
+static void rt61pci_config_lock_channel(struct rt2x00_dev *rt2x00dev,
+					struct rf_channel *rf,
+					const int txpower)
 {
-	struct rf_channel reg;
-	u8 bbp = 0;
+	u8 r3;
+	u8 r94;
+	u8 smart;
 
-	/*
-	 * Fill rf_reg structure.
-	 */
-	memcpy(&reg, &rt2x00dev->spec.channels[index], sizeof(reg));
+	rt2x00_set_field32(&rf->rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
+	rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset);
 
-	/*
-	 * Set TXpower.
-	 */
-	rt2x00_set_field32(&reg.rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
+	smart = !(rt2x00_rf(&rt2x00dev->chip, RF5225) ||
+		  rt2x00_rf(&rt2x00dev->chip, RF2527));
 
-	/*
-	 * Set Frequency offset.
-	 */
-	rt2x00_set_field32(&reg.rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset);
+	rt61pci_bbp_read(rt2x00dev, 3, &r3);
+	rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, smart);
+	rt61pci_bbp_write(rt2x00dev, 3, r3);
+
+	r94 = 6;
+	if (txpower > MAX_TXPOWER && txpower <= (MAX_TXPOWER + r94))
+		r94 += txpower - MAX_TXPOWER;
+	else if (txpower < MIN_TXPOWER && txpower >= (MIN_TXPOWER - r94))
+		r94 += txpower;
+	rt61pci_bbp_write(rt2x00dev, 94, r94);
 
-	rt61pci_rf_write(rt2x00dev, 1, reg.rf1);
-	rt61pci_rf_write(rt2x00dev, 2, reg.rf2);
-	rt61pci_rf_write(rt2x00dev, 3, reg.rf3 & ~0x00000004);
-	rt61pci_rf_write(rt2x00dev, 4, reg.rf4);
+	rt61pci_rf_write(rt2x00dev, 1, rf->rf1);
+	rt61pci_rf_write(rt2x00dev, 2, rf->rf2);
+	rt61pci_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
+	rt61pci_rf_write(rt2x00dev, 4, rf->rf4);
 
 	udelay(200);
 
-	rt61pci_rf_write(rt2x00dev, 1, reg.rf1);
-	rt61pci_rf_write(rt2x00dev, 2, reg.rf2);
-	rt61pci_rf_write(rt2x00dev, 3, reg.rf3 | 0x00000004);
-	rt61pci_rf_write(rt2x00dev, 4, reg.rf4);
+	rt61pci_rf_write(rt2x00dev, 1, rf->rf1);
+	rt61pci_rf_write(rt2x00dev, 2, rf->rf2);
+	rt61pci_rf_write(rt2x00dev, 3, rf->rf3 | 0x00000004);
+	rt61pci_rf_write(rt2x00dev, 4, rf->rf4);
 
 	udelay(200);
 
-	rt61pci_rf_write(rt2x00dev, 1, reg.rf1);
-	rt61pci_rf_write(rt2x00dev, 2, reg.rf2);
-	rt61pci_rf_write(rt2x00dev, 3, reg.rf3 & ~0x00000004);
-	rt61pci_rf_write(rt2x00dev, 4, reg.rf4);
-
-	rt61pci_bbp_read(rt2x00dev, 3, &bbp);
-	if (rt2x00_rf(&rt2x00dev->chip, RF5225) ||
-	    rt2x00_rf(&rt2x00dev->chip, RF2527))
-		bbp &= ~0x01;
-	else
-		bbp |= 0x01;
-	rt61pci_bbp_write(rt2x00dev, 3, bbp);
+	rt61pci_rf_write(rt2x00dev, 1, rf->rf1);
+	rt61pci_rf_write(rt2x00dev, 2, rf->rf2);
+	rt61pci_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
+	rt61pci_rf_write(rt2x00dev, 4, rf->rf4);
 
 	msleep(1);
 }
 
+static void rt61pci_config_channel(struct rt2x00_dev *rt2x00dev,
+				   const int index, const int channel,
+				   const int txpower)
+{
+	struct rf_channel rf;
+
+	/*
+	 * Fill rf_reg structure.
+	 */
+	memcpy(&rf, &rt2x00dev->spec.channels[index], sizeof(rf));
+
+	rt61pci_config_lock_channel(rt2x00dev, &rf, txpower);
+}
+
 static void rt61pci_config_txpower(struct rt2x00_dev *rt2x00dev,
 				   const int txpower)
 {
@@ -514,26 +523,7 @@ static void rt61pci_config_txpower(struct rt2x00_dev *rt2x00dev,
 	rt2x00_rf_read(rt2x00dev, 3, &rf.rf3);
 	rt2x00_rf_read(rt2x00dev, 4, &rf.rf4);
 
-	rt2x00_set_field32(&rf.rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
-
-	rt61pci_rf_write(rt2x00dev, 1, rf.rf1);
-	rt61pci_rf_write(rt2x00dev, 2, rf.rf2);
-	rt61pci_rf_write(rt2x00dev, 3, rf.rf3 & ~0x00000004);
-	rt61pci_rf_write(rt2x00dev, 4, rf.rf4);
-
-	udelay(200);
-
-	rt61pci_rf_write(rt2x00dev, 1, rf.rf1);
-	rt61pci_rf_write(rt2x00dev, 2, rf.rf2);
-	rt61pci_rf_write(rt2x00dev, 3, rf.rf3 | 0x00000004);
-	rt61pci_rf_write(rt2x00dev, 4, rf.rf4);
-
-	udelay(200);
-
-	rt61pci_rf_write(rt2x00dev, 1, rf.rf1);
-	rt61pci_rf_write(rt2x00dev, 2, rf.rf2);
-	rt61pci_rf_write(rt2x00dev, 3, rf.rf3 & ~0x00000004);
-	rt61pci_rf_write(rt2x00dev, 4, rf.rf4);
+	rt61pci_config_lock_channel(rt2x00dev, &rf, txpower);
 }
 
 static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 67a6644..f7017a8 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -428,52 +428,61 @@ static void rt73usb_config_phymode(struct rt2x00_dev *rt2x00dev,
 	rt73usb_config_rate(rt2x00dev, rate->val2);
 }
 
+static void rt73usb_config_lock_channel(struct rt2x00_dev *rt2x00dev,
+					struct rf_channel *rf,
+					const int txpower)
+{
+	u8 r3;
+	u8 r94;
+	u8 smart;
+
+	rt2x00_set_field32(&rf->rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
+	rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset);
+
+	smart = !(rt2x00_rf(&rt2x00dev->chip, RF5225) ||
+		  rt2x00_rf(&rt2x00dev->chip, RF2527));
+
+	rt73usb_bbp_read(rt2x00dev, 3, &r3);
+	rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, smart);
+	rt73usb_bbp_write(rt2x00dev, 3, r3);
+
+	r94 = 6;
+	if (txpower > MAX_TXPOWER && txpower <= (MAX_TXPOWER + r94))
+		r94 += txpower - MAX_TXPOWER;
+	else if (txpower < MIN_TXPOWER && txpower >= (MIN_TXPOWER - r94))
+		r94 += txpower;
+	rt73usb_bbp_write(rt2x00dev, 94, r94);
+
+	rt73usb_rf_write(rt2x00dev, 1, rf->rf1);
+	rt73usb_rf_write(rt2x00dev, 2, rf->rf2);
+	rt73usb_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
+	rt73usb_rf_write(rt2x00dev, 4, rf->rf4);
+
+	rt73usb_rf_write(rt2x00dev, 1, rf->rf1);
+	rt73usb_rf_write(rt2x00dev, 2, rf->rf2);
+	rt73usb_rf_write(rt2x00dev, 3, rf->rf3 | 0x00000004);
+	rt73usb_rf_write(rt2x00dev, 4, rf->rf4);
+
+	rt73usb_rf_write(rt2x00dev, 1, rf->rf1);
+	rt73usb_rf_write(rt2x00dev, 2, rf->rf2);
+	rt73usb_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
+	rt73usb_rf_write(rt2x00dev, 4, rf->rf4);
+
+	udelay(10);
+}
+
 static void rt73usb_config_channel(struct rt2x00_dev *rt2x00dev,
 				   const int index, const int channel,
 				   const int txpower)
 {
-	struct rf_channel reg;
-	u8 bbp = 0;
+	struct rf_channel rf;
 
 	/*
 	 * Fill rf_reg structure.
 	 */
-	memcpy(&reg, &rt2x00dev->spec.channels[index], sizeof(reg));
+	memcpy(&rf, &rt2x00dev->spec.channels[index], sizeof(rf));
 
-	/*
-	 * Set TXpower.
-	 */
-	rt2x00_set_field32(&reg.rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
-
-	/*
-	 * Set Frequency offset.
-	 */
-	rt2x00_set_field32(&reg.rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset);
-
-	rt73usb_bbp_read(rt2x00dev, 3, &bbp);
-	if (rt2x00_rf(&rt2x00dev->chip, RF5225) ||
-	    rt2x00_rf(&rt2x00dev->chip, RF2527))
-		bbp &= ~0x01;
-	else
-		bbp |= 0x01;
-	rt73usb_bbp_write(rt2x00dev, 3, bbp);
-
-	rt73usb_rf_write(rt2x00dev, 1, reg.rf1);
-	rt73usb_rf_write(rt2x00dev, 2, reg.rf2);
-	rt73usb_rf_write(rt2x00dev, 3, reg.rf3 & ~0x00000004);
-	rt73usb_rf_write(rt2x00dev, 4, reg.rf4);
-
-	rt73usb_rf_write(rt2x00dev, 1, reg.rf1);
-	rt73usb_rf_write(rt2x00dev, 2, reg.rf2);
-	rt73usb_rf_write(rt2x00dev, 3, reg.rf3 | 0x00000004);
-	rt73usb_rf_write(rt2x00dev, 4, reg.rf4);
-
-	rt73usb_rf_write(rt2x00dev, 1, reg.rf1);
-	rt73usb_rf_write(rt2x00dev, 2, reg.rf2);
-	rt73usb_rf_write(rt2x00dev, 3, reg.rf3 & ~0x00000004);
-	rt73usb_rf_write(rt2x00dev, 4, reg.rf4);
-
-	msleep(1);
+	rt73usb_config_lock_channel(rt2x00dev, &rf, txpower);
 }
 
 static void rt73usb_config_txpower(struct rt2x00_dev *rt2x00dev,
@@ -486,26 +495,7 @@ static void rt73usb_config_txpower(struct rt2x00_dev *rt2x00dev,
 	rt2x00_rf_read(rt2x00dev, 3, &rf.rf3);
 	rt2x00_rf_read(rt2x00dev, 4, &rf.rf4);
 
-	rt2x00_set_field32(&rf.rf3, RF3_TXPOWER, TXPOWER_TO_DEV(txpower));
-
-	rt73usb_rf_write(rt2x00dev, 1, rf.rf1);
-	rt73usb_rf_write(rt2x00dev, 2, rf.rf2);
-	rt73usb_rf_write(rt2x00dev, 3, rf.rf3 & ~0x00000004);
-	rt73usb_rf_write(rt2x00dev, 4, rf.rf4);
-
-	udelay(200);
-
-	rt73usb_rf_write(rt2x00dev, 1, rf.rf1);
-	rt73usb_rf_write(rt2x00dev, 2, rf.rf2);
-	rt73usb_rf_write(rt2x00dev, 3, rf.rf3 | 0x00000004);
-	rt73usb_rf_write(rt2x00dev, 4, rf.rf4);
-
-	udelay(200);
-
-	rt73usb_rf_write(rt2x00dev, 1, rf.rf1);
-	rt73usb_rf_write(rt2x00dev, 2, rf.rf2);
-	rt73usb_rf_write(rt2x00dev, 3, rf.rf3 & ~0x00000004);
-	rt73usb_rf_write(rt2x00dev, 4, rf.rf4);
+	rt73usb_config_lock_channel(rt2x00dev, &rf, txpower);
 }
 
 static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
-- 
1.5.3

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

* [PATCH 21/24] rt2x00: Add better CONFIG_PM checks
       [not found] <200709161403.11332.IvDoorn@gmail.com>
                   ` (19 preceding siblings ...)
  2007-09-16 12:19 ` [PATCH 20/24] rt2x00: Fix channel initialization Ivo van Doorn
@ 2007-09-16 12:19 ` Ivo van Doorn
  2007-09-16 12:19 ` [PATCH 22/24] rt2x00: Add start/stop handlers Ivo van Doorn
                   ` (2 subsequent siblings)
  23 siblings, 0 replies; 24+ messages in thread
From: Ivo van Doorn @ 2007-09-16 12:19 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, rt2400-devel

Put rt2x00lib suspend/resume handlers inside CONFIG_PM defines,
also declare rt2x00{pci,usb}_suspend/resume NULL when CONFIG_PM
is not not defined. This safes macro checks inside the drivers.

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

diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 28236dc..38e2188 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1671,10 +1671,8 @@ static struct pci_driver rt2400pci_driver = {
 	.id_table	= rt2400pci_device_table,
 	.probe		= rt2x00pci_probe,
 	.remove		= __devexit_p(rt2x00pci_remove),
-#ifdef CONFIG_PM
 	.suspend	= rt2x00pci_suspend,
 	.resume		= rt2x00pci_resume,
-#endif /* CONFIG_PM */
 };
 
 static int __init rt2400pci_init(void)
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index fc28631..f6115c6 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1982,10 +1982,8 @@ static struct pci_driver rt2500pci_driver = {
 	.id_table	= rt2500pci_device_table,
 	.probe		= rt2x00pci_probe,
 	.remove		= __devexit_p(rt2x00pci_remove),
-#ifdef CONFIG_PM
 	.suspend	= rt2x00pci_suspend,
 	.resume		= rt2x00pci_resume,
-#endif /* CONFIG_PM */
 };
 
 static int __init rt2500pci_init(void)
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 5bdf64f..847bd7f 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1819,10 +1819,8 @@ static struct usb_driver rt2500usb_driver = {
 	.id_table	= rt2500usb_device_table,
 	.probe		= rt2x00usb_probe,
 	.disconnect	= rt2x00usb_disconnect,
-#ifdef CONFIG_PM
 	.suspend	= rt2x00usb_suspend,
 	.resume		= rt2x00usb_resume,
-#endif /* CONFIG_PM */
 };
 
 static int __init rt2500usb_init(void)
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index b5f408c..c18875b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -797,7 +797,9 @@ int rt2x00mac_conf_tx(struct ieee80211_hw *hw, int queue,
  */
 int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev);
 void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev);
+#ifdef CONFIG_PM
 int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state);
 int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev);
+#endif /* CONFIG_PM */
 
 #endif /* RT2X00_H */
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 6992727..c0bdf63 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -1106,6 +1106,7 @@ EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev);
 /*
  * Device state handlers
  */
+#ifdef CONFIG_PM
 int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state)
 {
 	int retval;
@@ -1184,6 +1185,7 @@ exit:
 	return retval;
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_resume);
+#endif /* CONFIG_PM */
 
 /*
  * rt2x00lib module information.
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h
index 0a8b680..82adeac 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.h
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.h
@@ -119,6 +119,9 @@ void rt2x00pci_remove(struct pci_dev *pci_dev);
 #ifdef CONFIG_PM
 int rt2x00pci_suspend(struct pci_dev *pci_dev, pm_message_t state);
 int rt2x00pci_resume(struct pci_dev *pci_dev);
+#else
+#define rt2x00pci_suspend	NULL
+#define rt2x00pci_resume	NULL
 #endif /* CONFIG_PM */
 
 #endif /* RT2X00PCI_H */
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h
index f3be092..d4113e5 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.h
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.h
@@ -172,6 +172,9 @@ void rt2x00usb_disconnect(struct usb_interface *usb_intf);
 #ifdef CONFIG_PM
 int rt2x00usb_suspend(struct usb_interface *usb_intf, pm_message_t state);
 int rt2x00usb_resume(struct usb_interface *usb_intf);
+#else
+#define rt2x00usb_suspend	NULL
+#define rt2x00usb_resume	NULL
 #endif /* CONFIG_PM */
 
 #endif /* RT2X00USB_H */
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 6baa651..730bed5 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2585,10 +2585,8 @@ static struct pci_driver rt61pci_driver = {
 	.id_table	= rt61pci_device_table,
 	.probe		= rt2x00pci_probe,
 	.remove		= __devexit_p(rt2x00pci_remove),
-#ifdef CONFIG_PM
 	.suspend	= rt2x00pci_suspend,
 	.resume		= rt2x00pci_resume,
-#endif /* CONFIG_PM */
 };
 
 static int __init rt61pci_init(void)
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index f7017a8..b047c7c 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2106,10 +2106,8 @@ static struct usb_driver rt73usb_driver = {
 	.id_table	= rt73usb_device_table,
 	.probe		= rt2x00usb_probe,
 	.disconnect	= rt2x00usb_disconnect,
-#ifdef CONFIG_PM
 	.suspend	= rt2x00usb_suspend,
 	.resume		= rt2x00usb_resume,
-#endif /* CONFIG_PM */
 };
 
 static int __init rt73usb_init(void)
-- 
1.5.3

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

* [PATCH 22/24] rt2x00: Add start/stop handlers
       [not found] <200709161403.11332.IvDoorn@gmail.com>
                   ` (20 preceding siblings ...)
  2007-09-16 12:19 ` [PATCH 21/24] rt2x00: Add better CONFIG_PM checks Ivo van Doorn
@ 2007-09-16 12:19 ` Ivo van Doorn
  2007-09-16 12:19 ` [PATCH 23/24] rt2x00: Add additional bit to MAX_FRAME_UNIT Ivo van Doorn
  2007-09-16 12:19 ` [PATCH 24/24] rt2x00: Release rt2x00 2.0.8 Ivo van Doorn
  23 siblings, 0 replies; 24+ messages in thread
From: Ivo van Doorn @ 2007-09-16 12:19 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, rt2400-devel

With the patch by Johannes Berg, mandatory start and stop handlers
will be added to the mac80211 ops structure.
The patch has not yet been applied to wireless-dev, but this
patch will already create the handlers and will temporarily
be called from add_interface and remove_interface.

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2x00.h    |    2 +
 drivers/net/wireless/rt2x00/rt2x00dev.c |   73 ++--------------------------
 drivers/net/wireless/rt2x00/rt2x00lib.h |    4 +-
 drivers/net/wireless/rt2x00/rt2x00mac.c |   80 +++++++++++++++++++++++++++++--
 4 files changed, 84 insertions(+), 75 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index c18875b..1681749 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -776,6 +776,8 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
  */
 int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
 		 struct ieee80211_tx_control *control);
+int rt2x00mac_start(struct ieee80211_hw *hw);
+void rt2x00mac_stop(struct ieee80211_hw *hw);
 int rt2x00mac_add_interface(struct ieee80211_hw *hw,
 			    struct ieee80211_if_init_conf *conf);
 void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index c0bdf63..cd82eef 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -821,7 +821,7 @@ static void rt2x00lib_free_ring_entries(struct rt2x00_dev *rt2x00dev)
 	}
 }
 
-static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev)
+void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev)
 {
 	if (!__test_and_clear_bit(DEVICE_INITIALIZED, &rt2x00dev->flags))
 		return;
@@ -842,7 +842,7 @@ static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev)
 	rt2x00lib_free_ring_entries(rt2x00dev);
 }
 
-static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev)
+int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev)
 {
 	int status;
 
@@ -885,70 +885,6 @@ exit:
 	return status;
 }
 
-int rt2x00lib_init_interface(struct rt2x00_dev *rt2x00dev)
-{
-	struct interface *intf = &rt2x00dev->interface;
-	int status;
-
-	/*
-	 * If this is the first interface which is added,
-	 * we should load the firmware now.
-	 */
-	if (!test_bit(DEVICE_INITIALIZED, &rt2x00dev->flags) &&
-	    test_bit(REQUIRE_FIRMWARE, &rt2x00dev->flags)) {
-		status = rt2x00lib_load_firmware(rt2x00dev);
-		if (status)
-			return status;
-	}
-
-	/*
-	 * We should configure the MAC address before
-	 * the initialization starts.
-	 */
-	rt2x00lib_config_mac_addr(rt2x00dev, intf->mac);
-
-	/*
-	 * Initialize interface and enable the radio.
-	 */
-	if (!test_bit(DEVICE_INITIALIZED, &rt2x00dev->flags)) {
-		/*
-		 * Initialize the device.
-		 */
-		status = rt2x00lib_initialize(rt2x00dev);
-		if (status)
-			return status;
-
-		/*
-		 * Enable radio.
-		 */
-		status = rt2x00lib_enable_radio(rt2x00dev);
-		if (status) {
-			rt2x00lib_uninitialize(rt2x00dev);
-			return status;
-		}
-	}
-
-	return 0;
-}
-
-void rt2x00lib_deinit_interface(struct rt2x00_dev *rt2x00dev)
-{
-	struct interface *intf = &rt2x00dev->interface;
-
-	/*
-	 * If no interfaces are present, we should disable the radio
-	 * Otherwise configure the mac_address and bssid and check
-	 * which interface needs to be initialized.
-	 */
-	if (!is_monitor_present(intf) && !is_interface_present(intf))
-		rt2x00lib_disable_radio(rt2x00dev);
-	else if (is_monitor_present(intf) ^ is_interface_present(intf)) {
-		rt2x00lib_config_mac_addr(rt2x00dev, intf->mac);
-		rt2x00lib_config_bssid(rt2x00dev, intf->bssid);
-		rt2x00lib_config_type(rt2x00dev, intf->type);
-	}
-}
-
 /*
  * driver allocation handlers.
  */
@@ -1148,7 +1084,7 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
 	/*
 	 * Reinitialize device and all active interfaces.
 	 */
-	retval = rt2x00lib_init_interface(rt2x00dev);
+	retval = rt2x00mac_start(rt2x00dev->hw);
 	if (retval)
 		goto exit;
 
@@ -1159,9 +1095,10 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
 	if (retval)
 		goto exit;
 
+	rt2x00lib_config_mac_addr(rt2x00dev, intf->mac);
+	rt2x00lib_config_bssid(rt2x00dev, intf->bssid);
 	rt2x00lib_config_type(rt2x00dev, intf->type);
 	rt2x00lib_config_packet_filter(rt2x00dev, intf->filter);
-	rt2x00lib_config_bssid(rt2x00dev, intf->bssid);
 
 	/*
 	 * When in Master or Ad-hoc mode,
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index 454e022..3324090 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -43,8 +43,8 @@ void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev);
 /*
  * Initialization handlers.
  */
-int rt2x00lib_init_interface(struct rt2x00_dev *rt2x00dev);
-void rt2x00lib_deinit_interface(struct rt2x00_dev *rt2x00dev);
+int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev);
+void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev);
 
 /*
  * Configuration handlers.
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 006154c..778ed41 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -121,6 +121,56 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
 }
 EXPORT_SYMBOL_GPL(rt2x00mac_tx);
 
+int rt2x00mac_start(struct ieee80211_hw *hw)
+{
+	struct rt2x00_dev *rt2x00dev = hw->priv;
+	int status;
+
+	if (test_bit(DEVICE_INITIALIZED, &rt2x00dev->flags))
+		return 0;
+
+	/*
+	 * If this is the first interface which is added,
+	 * we should load the firmware now.
+	 */
+	if (test_bit(REQUIRE_FIRMWARE, &rt2x00dev->flags)) {
+		status = rt2x00lib_load_firmware(rt2x00dev);
+		if (status)
+			return status;
+	}
+
+	/*
+	 * Initialize the device.
+	 */
+	status = rt2x00lib_initialize(rt2x00dev);
+	if (status)
+		return status;
+
+	/*
+	 * Enable radio.
+	 */
+	status = rt2x00lib_enable_radio(rt2x00dev);
+	if (status) {
+		rt2x00lib_uninitialize(rt2x00dev);
+		return status;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rt2x00mac_start);
+
+void rt2x00mac_stop(struct ieee80211_hw *hw)
+{
+	struct rt2x00_dev *rt2x00dev = hw->priv;
+
+	/*
+	 * Perhaps we can add something smarter here,
+	 * but for now just disabling the radio should do.
+	 */
+	rt2x00lib_disable_radio(rt2x00dev);
+}
+EXPORT_SYMBOL_GPL(rt2x00mac_stop);
+
 int rt2x00mac_add_interface(struct ieee80211_hw *hw,
 			    struct ieee80211_if_init_conf *conf)
 {
@@ -135,6 +185,14 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
 		return -ENOBUFS;
 
 	/*
+	 * HACK: Placeholder until start/stop handler has been
+	 * added to the mac80211 callback functions structure.
+	 */
+	retval = rt2x00mac_start(hw);
+	if (retval)
+		return retval;
+
+	/*
 	 * We support muliple monitor mode interfaces.
 	 * All we need to do is increase the monitor_count.
 	 */
@@ -149,13 +207,13 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
 		intf->filter = 0;
 	}
 
-	retval = rt2x00lib_init_interface(rt2x00dev);
-	if (retval)
-		return retval;
-
 	/*
 	 * Configure interface.
+	 * The MAC adddress must be configured after the device
+	 * has been initialized. Else the device can reset the
+	 * MAC registers.
 	 */
+	rt2x00lib_config_mac_addr(rt2x00dev, intf->mac);
 	rt2x00lib_config_type(rt2x00dev, conf->type);
 	rt2x00lib_config_packet_filter(rt2x00dev, intf->filter);
 
@@ -189,7 +247,19 @@ void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
 		intf->filter = 0;
 	}
 
-	rt2x00lib_deinit_interface(rt2x00dev);
+	/*
+	 * Make sure the bssid and mac address registers
+	 * are cleared to prevent false ACKing of frames.
+	 */
+	rt2x00lib_config_mac_addr(rt2x00dev, intf->mac);
+	rt2x00lib_config_bssid(rt2x00dev, intf->bssid);
+	rt2x00lib_config_type(rt2x00dev, intf->type);
+
+	/*
+	 * HACK: Placeholder untill start/stop handler has been
+	 * added to the mac80211 callback functions structure.
+	 */
+	rt2x00mac_stop(hw);
 }
 EXPORT_SYMBOL_GPL(rt2x00mac_remove_interface);
 
-- 
1.5.3

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

* [PATCH 23/24] rt2x00: Add additional bit to MAX_FRAME_UNIT
       [not found] <200709161403.11332.IvDoorn@gmail.com>
                   ` (21 preceding siblings ...)
  2007-09-16 12:19 ` [PATCH 22/24] rt2x00: Add start/stop handlers Ivo van Doorn
@ 2007-09-16 12:19 ` Ivo van Doorn
  2007-09-16 12:19 ` [PATCH 24/24] rt2x00: Release rt2x00 2.0.8 Ivo van Doorn
  23 siblings, 0 replies; 24+ messages in thread
From: Ivo van Doorn @ 2007-09-16 12:19 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, rt2400-devel

Legacy driver indicated that the MAX_FRAME_UNIT register
was 11 bits long. _but_ they do write 12 bits to the register.
Increase the register definition to accept the 12th bit.

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

diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h
index f24bff3..6721d7d 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.h
+++ b/drivers/net/wireless/rt2x00/rt61pci.h
@@ -262,7 +262,7 @@ struct hw_pairwise_ta_entry {
  * MAC_CSR6: Maximum frame length register.
  */
 #define MAC_CSR6			0x3018
-#define MAC_CSR6_MAX_FRAME_UNIT		FIELD32(0x000007ff)
+#define MAC_CSR6_MAX_FRAME_UNIT		FIELD32(0x00000fff)
 
 /*
  * MAC_CSR7: Reserved
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h
index 82f4e76..5d63a1a 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.h
+++ b/drivers/net/wireless/rt2x00/rt73usb.h
@@ -174,7 +174,7 @@ struct hw_pairwise_ta_entry {
  * MAC_CSR6: Maximum frame length register.
  */
 #define MAC_CSR6			0x3018
-#define MAC_CSR6_MAX_FRAME_UNIT		FIELD32(0x000007ff)
+#define MAC_CSR6_MAX_FRAME_UNIT		FIELD32(0x00000fff)
 
 /*
  * MAC_CSR7: Reserved
-- 
1.5.3

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

* [PATCH 24/24] rt2x00: Release rt2x00 2.0.8
       [not found] <200709161403.11332.IvDoorn@gmail.com>
                   ` (22 preceding siblings ...)
  2007-09-16 12:19 ` [PATCH 23/24] rt2x00: Add additional bit to MAX_FRAME_UNIT Ivo van Doorn
@ 2007-09-16 12:19 ` Ivo van Doorn
  23 siblings, 0 replies; 24+ messages in thread
From: Ivo van Doorn @ 2007-09-16 12:19 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, rt2400-devel


Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
 drivers/net/wireless/rt2x00/rt2x00.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 1681749..80b079d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -42,7 +42,7 @@
  * Module information.
  * DRV_NAME should be set within the individual module source files.
  */
-#define DRV_VERSION	"2.0.7"
+#define DRV_VERSION	"2.0.8"
 #define DRV_PROJECT	"http://rt2x00.serialmonkey.com"
 
 /*
-- 
1.5.3


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

end of thread, other threads:[~2007-09-16 12:08 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <200709161403.11332.IvDoorn@gmail.com>
2007-09-16 12:17 ` [PATCH 1/24] rt2x00: Remove firmware not-NULL check Ivo van Doorn
2007-09-16 12:17 ` [PATCH 2/24] rt2x00: Don't check for IEEE80211_TXCTL_REQ_TX_STATUS Ivo van Doorn
2007-09-16 12:18 ` [PATCH 3/24] rt2x00: Cleanup rxdone Ivo van Doorn
2007-09-16 12:18 ` [PATCH 4/24] rt2x00: Don't allow configuration calls when uninitialized Ivo van Doorn
2007-09-16 12:18 ` [PATCH 5/24] rt2x00: Fix rt61pci and rt73usb beacon handling Ivo van Doorn
2007-09-16 12:18 ` [PATCH 6/24] rt2x00: Recalculate link quality Ivo van Doorn
2007-09-16 12:18 ` [PATCH 7/24] rt2x00: Cleanup entry->flags Ivo van Doorn
2007-09-16 12:18 ` [PATCH 8/24] rt2x00: Reduce LNA flags Ivo van Doorn
2007-09-16 12:18 ` [PATCH 9/24] rt2x00: Rework RT61 and RT73 Antenna handling Ivo van Doorn
2007-09-16 12:18 ` [PATCH 10/24] rt2x00: Rename DEVICE_SUPPORT_ATIM to REQUIRE_BEACON_RING Ivo van Doorn
2007-09-16 12:18 ` [PATCH 11/24] rt2x00: Remove rt2x00mac_reset() Ivo van Doorn
2007-09-16 12:18 ` [PATCH 12/24] rt2x00: Fix system freeze on device removal Ivo van Doorn
2007-09-16 12:18 ` [PATCH 13/24] rt2x00: Reduce magic value writing to device Ivo van Doorn
2007-09-16 12:19 ` [PATCH 14/24] rt2x00: New USB ID's for rt73usb and rt2500usb Ivo van Doorn
2007-09-16 12:19 ` [PATCH 15/24] rt2x00: Beacon ring entries should have QID_MGMT Ivo van Doorn
2007-09-16 12:19 ` [PATCH 16/24] rt2x00: Fix DEV_RATEBIT_ definitions Ivo van Doorn
2007-09-16 12:19 ` [PATCH 17/24] rt2x00: Fix rfkill handling Ivo van Doorn
2007-09-16 12:19 ` [PATCH 18/24] rt2x00: Merge allocation/free register components Ivo van Doorn
2007-09-16 12:19 ` [PATCH 19/24] rt2x00: macro's shouldn't use hidden arguments Ivo van Doorn
2007-09-16 12:19 ` [PATCH 20/24] rt2x00: Fix channel initialization Ivo van Doorn
2007-09-16 12:19 ` [PATCH 21/24] rt2x00: Add better CONFIG_PM checks Ivo van Doorn
2007-09-16 12:19 ` [PATCH 22/24] rt2x00: Add start/stop handlers Ivo van Doorn
2007-09-16 12:19 ` [PATCH 23/24] rt2x00: Add additional bit to MAX_FRAME_UNIT Ivo van Doorn
2007-09-16 12:19 ` [PATCH 24/24] rt2x00: Release rt2x00 2.0.8 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).