* [RFC/RFT 1/5] rt2x00: change beaconing locking
@ 2014-06-04 13:19 Stanislaw Gruszka
2014-06-04 13:19 ` [RFC/RFT 2/5] rt2x00: change beaconing setup on RT2800 Stanislaw Gruszka
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Stanislaw Gruszka @ 2014-06-04 13:19 UTC (permalink / raw)
To: users; +Cc: linux-wireless, Matthias Fend
This patch is needed for further changes to keep global variables
consisent when chaning beaconing on diffrent vif's.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
drivers/net/wireless/rt2x00/rt2x00dev.c | 7 +++++--
drivers/net/wireless/rt2x00/rt2x00mac.c | 6 ++----
drivers/net/wireless/rt2x00/rt2x00queue.c | 21 ++-------------------
3 files changed, 9 insertions(+), 25 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 2bde672..72e3e81 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -141,8 +141,11 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
return;
- if (test_and_clear_bit(DELAYED_UPDATE_BEACON, &intf->delayed_flags))
+ if (test_and_clear_bit(DELAYED_UPDATE_BEACON, &intf->delayed_flags)) {
+ mutex_lock(&intf->beacon_skb_mutex);
rt2x00queue_update_beacon(rt2x00dev, vif);
+ mutex_unlock(&intf->beacon_skb_mutex);
+ }
}
static void rt2x00lib_intf_scheduled(struct work_struct *work)
@@ -216,7 +219,7 @@ static void rt2x00lib_beaconupdate_iter(void *data, u8 *mac,
* never be called for USB devices.
*/
WARN_ON(rt2x00_is_usb(rt2x00dev));
- rt2x00queue_update_beacon_locked(rt2x00dev, vif);
+ rt2x00queue_update_beacon(rt2x00dev, vif);
}
void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 212ac48..0aad22d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -624,6 +624,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
* Start/stop beaconing.
*/
if (changes & BSS_CHANGED_BEACON_ENABLED) {
+ mutex_lock(&intf->beacon_skb_mutex);
if (!bss_conf->enable_beacon && intf->enable_beacon) {
rt2x00dev->intf_beaconing--;
intf->enable_beacon = false;
@@ -639,9 +640,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
* Last beaconing interface disabled
* -> stop beacon queue.
*/
- mutex_lock(&intf->beacon_skb_mutex);
rt2x00queue_stop_queue(rt2x00dev->bcn);
- mutex_unlock(&intf->beacon_skb_mutex);
}
} else if (bss_conf->enable_beacon && !intf->enable_beacon) {
rt2x00dev->intf_beaconing++;
@@ -658,11 +657,10 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
* First beaconing interface enabled
* -> start beacon queue.
*/
- mutex_lock(&intf->beacon_skb_mutex);
rt2x00queue_start_queue(rt2x00dev->bcn);
- mutex_unlock(&intf->beacon_skb_mutex);
}
}
+ mutex_unlock(&intf->beacon_skb_mutex);
}
/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 5642ccc..8e68f87 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -754,8 +754,6 @@ int rt2x00queue_clear_beacon(struct rt2x00_dev *rt2x00dev,
if (unlikely(!intf->beacon))
return -ENOBUFS;
- mutex_lock(&intf->beacon_skb_mutex);
-
/*
* Clean up the beacon skb.
*/
@@ -768,13 +766,11 @@ int rt2x00queue_clear_beacon(struct rt2x00_dev *rt2x00dev,
if (rt2x00dev->ops->lib->clear_beacon)
rt2x00dev->ops->lib->clear_beacon(intf->beacon);
- mutex_unlock(&intf->beacon_skb_mutex);
-
return 0;
}
-int rt2x00queue_update_beacon_locked(struct rt2x00_dev *rt2x00dev,
- struct ieee80211_vif *vif)
+int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
+ struct ieee80211_vif *vif)
{
struct rt2x00_intf *intf = vif_to_intf(vif);
struct skb_frame_desc *skbdesc;
@@ -815,19 +811,6 @@ int rt2x00queue_update_beacon_locked(struct rt2x00_dev *rt2x00dev,
}
-int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
- struct ieee80211_vif *vif)
-{
- struct rt2x00_intf *intf = vif_to_intf(vif);
- int ret;
-
- mutex_lock(&intf->beacon_skb_mutex);
- ret = rt2x00queue_update_beacon_locked(rt2x00dev, vif);
- mutex_unlock(&intf->beacon_skb_mutex);
-
- return ret;
-}
-
bool rt2x00queue_for_each_entry(struct data_queue *queue,
enum queue_index start,
enum queue_index end,
--
1.8.3.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [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
end of thread, other threads:[~2014-06-05 11:52 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 ` [RFC/RFT 4/5] rt2x00: change order when stop beaconing 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
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).