* [RFC/RFT 2/5] rt2x00: change beaconing setup on RT2800
2014-06-04 13:19 [RFC/RFT 1/5] rt2x00: change beaconing locking Stanislaw Gruszka
@ 2014-06-04 13:19 ` Stanislaw Gruszka
2014-06-04 13:19 ` [RFC/RFT 3/5] rt2x00: change default MAC_BSSID_DW1_BSS_BCN_NUM Stanislaw Gruszka
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Stanislaw Gruszka @ 2014-06-04 13:19 UTC (permalink / raw)
To: users; +Cc: linux-wireless, Matthias Fend
As reported by Matthias, on 5572 chip, even if we clear up TXWI
of corresponding beacon, hardware still try to send it or do other
action that increase power consumption peak up to 1A.
To avoid the issue, setup beaconing dynamically by configuring offsets
of currently active beacons and MAC_BSSID_DW1_BSS_BCN_NUM variable,
which limit number of beacons that hardware will try to send.
Reported-by: Matthias Fend <Matthias.Fend@wolfvision.net>
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 45 +++++++++++++++++++++++++++++++
drivers/net/wireless/rt2x00/rt2x00queue.h | 1 +
2 files changed, 46 insertions(+)
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index c17fcf2..c45b2d3 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -947,6 +947,40 @@ static inline u8 rt2800_get_beacon_offset(struct rt2x00_dev *rt2x00dev,
return BEACON_BASE_TO_OFFSET(rt2800_hw_beacon_base(rt2x00dev, index));
}
+static void rt2800_update_beacons_setup(struct rt2x00_dev *rt2x00dev)
+{
+ struct data_queue *queue = rt2x00dev->bcn;
+ struct queue_entry *entry;
+ int i, bcn_num = 0;
+ u64 off, reg = 0;
+ u32 bssid_dw1;
+
+ /*
+ * Setup offsets of all active beacons in BCN_OFFSET{0,1} registers.
+ */
+ for (i = 0; i < queue->limit; i++) {
+ entry = &queue->entries[i];
+ if (!test_bit(ENTRY_BCN_ENABLED, &entry->flags))
+ continue;
+ off = rt2800_get_beacon_offset(rt2x00dev, entry->entry_idx);
+ reg |= off << (8 * bcn_num);
+ bcn_num++;
+ }
+
+ WARN_ON_ONCE(bcn_num != rt2x00dev->intf_beaconing);
+
+ rt2800_register_write(rt2x00dev, BCN_OFFSET0, (u32) reg);
+ rt2800_register_write(rt2x00dev, BCN_OFFSET1, (u32) (reg >> 32));
+
+ /*
+ * H/W sends up to MAC_BSSID_DW1_BSS_BCN_NUM + 1 consecutive beacons.
+ */
+ rt2800_register_read(rt2x00dev, MAC_BSSID_DW1, &bssid_dw1);
+ rt2x00_set_field32(&bssid_dw1, MAC_BSSID_DW1_BSS_BCN_NUM,
+ bcn_num > 0 ? bcn_num - 1 : 0);
+ rt2800_register_write(rt2x00dev, MAC_BSSID_DW1, bssid_dw1);
+}
+
void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
{
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
@@ -1003,6 +1037,12 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
entry->skb->len + padding_len);
+ __set_bit(ENTRY_BCN_ENABLED, &entry->flags);
+
+ /*
+ * Change global beacons settings.
+ */
+ rt2800_update_beacons_setup(rt2x00dev);
/*
* Restore beaconing state.
@@ -1053,8 +1093,13 @@ void rt2800_clear_beacon(struct queue_entry *entry)
* Clear beacon.
*/
rt2800_clear_beacon_register(rt2x00dev, entry->entry_idx);
+ __clear_bit(ENTRY_BCN_ENABLED, &entry->flags);
/*
+ * Change global beacons settings.
+ */
+ rt2800_update_beacons_setup(rt2x00dev);
+ /*
* Restore beaconing state.
*/
rt2800_register_write(rt2x00dev, BCN_TIME_CFG, orig_reg);
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index c48125b..2233b91 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -353,6 +353,7 @@ struct txentry_desc {
*/
enum queue_entry_flags {
ENTRY_BCN_ASSIGNED,
+ ENTRY_BCN_ENABLED,
ENTRY_OWNER_DEVICE_DATA,
ENTRY_DATA_PENDING,
ENTRY_DATA_IO_FAILED,
--
1.8.3.1
^ permalink raw reply related [flat|nested] 6+ messages in thread* [RFC/RFT 3/5] rt2x00: change default MAC_BSSID_DW1_BSS_BCN_NUM
2014-06-04 13:19 [RFC/RFT 1/5] rt2x00: change beaconing locking Stanislaw Gruszka
2014-06-04 13:19 ` [RFC/RFT 2/5] rt2x00: change beaconing setup on RT2800 Stanislaw Gruszka
@ 2014-06-04 13:19 ` Stanislaw Gruszka
2014-06-04 13:19 ` [RFC/RFT 4/5] rt2x00: change order when stop beaconing Stanislaw Gruszka
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Stanislaw Gruszka @ 2014-06-04 13:19 UTC (permalink / raw)
To: users; +Cc: linux-wireless, Matthias Fend
We setup MAC_BSSID_DW1_BSS_BCN_NUM dynamically when numbers of active
beacons increase. Change default to 0 to tell hardware that we want to
send only one beacon as default.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index c45b2d3..a9cdddd 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -1601,7 +1601,7 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf,
if (!is_zero_ether_addr((const u8 *)conf->bssid)) {
reg = le32_to_cpu(conf->bssid[1]);
rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_ID_MASK, 3);
- rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_BCN_NUM, 7);
+ rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_BCN_NUM, 0);
conf->bssid[1] = cpu_to_le32(reg);
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 6+ messages in thread* [RFC/RFT 4/5] rt2x00: change order when stop beaconing
2014-06-04 13:19 [RFC/RFT 1/5] rt2x00: change beaconing locking Stanislaw Gruszka
2014-06-04 13:19 ` [RFC/RFT 2/5] rt2x00: change beaconing setup on RT2800 Stanislaw Gruszka
2014-06-04 13:19 ` [RFC/RFT 3/5] rt2x00: change default MAC_BSSID_DW1_BSS_BCN_NUM Stanislaw Gruszka
@ 2014-06-04 13:19 ` Stanislaw Gruszka
2014-06-04 13:19 ` [RFC/RFT 5/5] rt2x00: do not initialize BCN_OFFSET registers Stanislaw Gruszka
2014-06-05 11:51 ` [RFC/RFT 1/5] rt2x00: change beaconing locking Stanislaw Gruszka
4 siblings, 0 replies; 6+ messages in thread
From: Stanislaw Gruszka @ 2014-06-04 13:19 UTC (permalink / raw)
To: users; +Cc: linux-wireless, Matthias Fend
When no beaconing is needed, first stop beacon queue (disable beaconing
globally) to avoid possible sending of not prepared beacon on short
period after clearing beacon and before stop of BCN queue.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
drivers/net/wireless/rt2x00/rt2x00mac.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 0aad22d..b144802 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -628,12 +628,6 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
if (!bss_conf->enable_beacon && intf->enable_beacon) {
rt2x00dev->intf_beaconing--;
intf->enable_beacon = false;
- /*
- * Clear beacon in the H/W for this vif. This is needed
- * to disable beaconing on this particular interface
- * and keep it running on other interfaces.
- */
- rt2x00queue_clear_beacon(rt2x00dev, vif);
if (rt2x00dev->intf_beaconing == 0) {
/*
@@ -642,6 +636,12 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
*/
rt2x00queue_stop_queue(rt2x00dev->bcn);
}
+ /*
+ * Clear beacon in the H/W for this vif. This is needed
+ * to disable beaconing on this particular interface
+ * and keep it running on other interfaces.
+ */
+ rt2x00queue_clear_beacon(rt2x00dev, vif);
} else if (bss_conf->enable_beacon && !intf->enable_beacon) {
rt2x00dev->intf_beaconing++;
intf->enable_beacon = true;
--
1.8.3.1
^ permalink raw reply related [flat|nested] 6+ messages in thread* [RFC/RFT 5/5] rt2x00: do not initialize BCN_OFFSET registers
2014-06-04 13:19 [RFC/RFT 1/5] rt2x00: change beaconing locking Stanislaw Gruszka
` (2 preceding siblings ...)
2014-06-04 13:19 ` [RFC/RFT 4/5] rt2x00: change order when stop beaconing Stanislaw Gruszka
@ 2014-06-04 13:19 ` Stanislaw Gruszka
2014-06-05 11:51 ` [RFC/RFT 1/5] rt2x00: change beaconing locking Stanislaw Gruszka
4 siblings, 0 replies; 6+ messages in thread
From: Stanislaw Gruszka @ 2014-06-04 13:19 UTC (permalink / raw)
To: users; +Cc: linux-wireless, Matthias Fend
We setup BCN_OFFSET{0,1} registers dinamicly, don't have to
initialize them.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 22 ----------------------
1 file changed, 22 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index a9cdddd..893c9d5 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -4562,28 +4562,6 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
if (ret)
return ret;
- rt2800_register_read(rt2x00dev, BCN_OFFSET0, ®);
- rt2x00_set_field32(®, BCN_OFFSET0_BCN0,
- rt2800_get_beacon_offset(rt2x00dev, 0));
- rt2x00_set_field32(®, BCN_OFFSET0_BCN1,
- rt2800_get_beacon_offset(rt2x00dev, 1));
- rt2x00_set_field32(®, BCN_OFFSET0_BCN2,
- rt2800_get_beacon_offset(rt2x00dev, 2));
- rt2x00_set_field32(®, BCN_OFFSET0_BCN3,
- rt2800_get_beacon_offset(rt2x00dev, 3));
- rt2800_register_write(rt2x00dev, BCN_OFFSET0, reg);
-
- rt2800_register_read(rt2x00dev, BCN_OFFSET1, ®);
- rt2x00_set_field32(®, BCN_OFFSET1_BCN4,
- rt2800_get_beacon_offset(rt2x00dev, 4));
- rt2x00_set_field32(®, BCN_OFFSET1_BCN5,
- rt2800_get_beacon_offset(rt2x00dev, 5));
- rt2x00_set_field32(®, BCN_OFFSET1_BCN6,
- rt2800_get_beacon_offset(rt2x00dev, 6));
- rt2x00_set_field32(®, BCN_OFFSET1_BCN7,
- rt2800_get_beacon_offset(rt2x00dev, 7));
- rt2800_register_write(rt2x00dev, BCN_OFFSET1, reg);
-
rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, 0x0000013f);
rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003);
--
1.8.3.1
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [RFC/RFT 1/5] rt2x00: change beaconing locking
2014-06-04 13:19 [RFC/RFT 1/5] rt2x00: change beaconing locking Stanislaw Gruszka
` (3 preceding siblings ...)
2014-06-04 13:19 ` [RFC/RFT 5/5] rt2x00: do not initialize BCN_OFFSET registers Stanislaw Gruszka
@ 2014-06-05 11:51 ` Stanislaw Gruszka
4 siblings, 0 replies; 6+ messages in thread
From: Stanislaw Gruszka @ 2014-06-05 11:51 UTC (permalink / raw)
To: users; +Cc: linux-wireless, Matthias Fend
On Wed, Jun 04, 2014 at 03:19:11PM +0200, Stanislaw Gruszka wrote:
> This patch is needed for further changes to keep global variables
> consisent when chaning beaconing on diffrent vif's.
I tested patches on IBSS an AP single and multi-bss mode. Beaconing
works, I will post official patches soon (with some changelog spell
fixes).
Stanislaw
^ permalink raw reply [flat|nested] 6+ messages in thread