[rt2x00-users] [PATCH 3/4] rt2x00: use new beacon handlers in rt2800pci

Helmut Schaa helmut.schaa at googlemail.com
Thu Jul 1 02:29:59 AEST 2010


Use the new beacon handler rt2x00pci_pretbtt to update the beacon
prior to transmission and rt2x00pci_beacondone to send out buffered
broadcast and multicast frames after a DTIM beacon.

Also set up the pre_tbtt timer to get notified when to update the
beacon. The timer is configured to 1ms which seems to be early enough
on an rt3052 SoC.

Signed-off-by: Helmut Schaa <helmut.schaa at googlemail.com>
---
 drivers/net/wireless/rt2x00/rt2800.h    |    8 +++++++-
 drivers/net/wireless/rt2x00/rt2800lib.c |   17 +++++++++++++++++
 drivers/net/wireless/rt2x00/rt2800pci.c |   27 ++++++++++++++++++++++-----
 3 files changed, 46 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 3ed87ba..80a08fb 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -719,14 +719,20 @@
 #define TBTT_TIMER			0x1124
 
 /*
- * INT_TIMER_CFG:
+ * INT_TIMER_CFG: timer configuration
+ * GP_TIMER: period of general purpose timer in units of 1/16 TU
+ * PRE_TBTT_TIMER: leadtime to tbtt for pretbtt interrupt in units of 1/16 TU
  */
 #define INT_TIMER_CFG			0x1128
+#define INT_TIMER_CFG_PRE_TBTT_TIMER	FIELD32(0x0000ffff)
+#define INT_TIMER_CFG_GP_TIMER		FIELD32(0xffff0000)
 
 /*
  * INT_TIMER_EN: GP-timer and pre-tbtt Int enable
  */
 #define INT_TIMER_EN			0x112c
+#define INT_TIMER_EN_PRE_TBTT_TIMER	FIELD32(0x00000001)
+#define INT_TIMER_EN_GP_TIMER		FIELD32(0x00000002)
 
 /*
  * CH_IDLE_STA: channel idle time
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index d3cf0cc..de4e0f6 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -762,6 +762,23 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf,
 		rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE,
 				   (conf->sync == TSF_SYNC_BEACON));
 		rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+
+		if (conf->sync == TSF_SYNC_NONE) {
+			/*
+			 * Enable pre tbtt timer in AP mode
+			 */
+			rt2800_register_read(rt2x00dev, INT_TIMER_CFG, &reg);
+			rt2x00_set_field32(&reg, INT_TIMER_CFG_PRE_TBTT_TIMER, 1 << 4);
+			rt2800_register_write(rt2x00dev, INT_TIMER_CFG, reg);
+
+			rt2800_register_read(rt2x00dev, INT_TIMER_EN, &reg);
+			rt2x00_set_field32(&reg, INT_TIMER_EN_PRE_TBTT_TIMER, 1);	
+			rt2800_register_write(rt2x00dev, INT_TIMER_EN, reg);
+		} else {
+			rt2800_register_read(rt2x00dev, INT_TIMER_EN, &reg);
+			rt2x00_set_field32(&reg, INT_TIMER_EN_PRE_TBTT_TIMER, 0);
+			rt2800_register_write(rt2x00dev, INT_TIMER_EN, reg);
+		}
 	}
 
 	if (flags & CONFIG_UPDATE_MAC) {
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 6f11760..870a0b4 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -943,22 +943,33 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance)
 
 	if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
 		return IRQ_HANDLED;
+	/*
+	 * 1 - pre tbtt interrupt -> update the beacon.
+	 */
+	if (rt2x00_get_field32(reg, INT_SOURCE_CSR_PRE_TBTT))
+		rt2x00pci_pretbtt(rt2x00dev);
 
 	/*
-	 * 1 - Rx ring done interrupt.
+	 * 2 - tbtt interrupt -> send out buffered bc/mc traffic.
+	 */
+	if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TBTT))
+		rt2x00pci_beacondone(rt2x00dev);
+
+	/*
+	 * 3 - Rx ring done interrupt.
 	 */
 	if (rt2x00_get_field32(reg, INT_SOURCE_CSR_RX_DONE))
 		rt2x00pci_rxdone(rt2x00dev);
 
+	/*
+	 * 4 - Tx done interrupt.
+	 */
 	if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS))
 		rt2800pci_txdone(rt2x00dev);
 
 	/*
-	 * Current beacon was sent out, fetch the next one
+	 * 5 - Auto wakeup interrupt.
 	 */
-	if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TBTT))
-		rt2x00lib_beacondone(rt2x00dev);
-
 	if (rt2x00_get_field32(reg, INT_SOURCE_CSR_AUTO_WAKEUP))
 		rt2800pci_wakeup(rt2x00dev);
 
@@ -1029,6 +1040,12 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
 	__set_bit(DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, &rt2x00dev->flags);
 
 	/*
+	 * This device has a pre tbtt interrupt and thus fetches
+	 * a new beacon directly prior to transmission
+	 */
+	__set_bit(DRIVER_SUPPORT_PRE_TBTT_INTERRUPT, &rt2x00dev->flags);
+
+	/*
 	 * This device requires firmware.
 	 */
 	if (!rt2x00_is_soc(rt2x00dev))
-- 
1.6.4.2



More information about the users mailing list