* [PATCH v2] mac80211: dynamic short slot time for MBSSs
@ 2013-01-26 20:37 Thomas Pedersen
2013-01-26 22:58 ` Johannes Berg
2013-01-26 23:04 ` Johannes Berg
0 siblings, 2 replies; 6+ messages in thread
From: Thomas Pedersen @ 2013-01-26 20:37 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, devel, Thomas Pedersen
The standard mandates mesh STAs to set the ERP Short Slot
Time capability info bit in beacons to 0. Even though this
is their way of disallowing short slot time for mesh STAs,
there should be no harm in enabling it if we determine all
STAs in the current MBSS support ERP rates.
Increases throughput about 20% for legacy rates when
enabled.
Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
---
v2:
fix survey logic
net/mac80211/mesh.c | 5 ----
net/mac80211/mesh_plink.c | 67 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 67 insertions(+), 5 deletions(-)
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 694e273..f920da1 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -629,11 +629,6 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
sdata->vif.bss_conf.basic_rates =
ieee80211_mandatory_rates(local, band);
- if (band == IEEE80211_BAND_5GHZ) {
- sdata->vif.bss_conf.use_short_slot = true;
- changed |= BSS_CHANGED_ERP_SLOT;
- }
-
ieee80211_bss_info_change_notify(sdata, changed);
netif_carrier_on(sdata->dev);
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 4e1d406..f79ab88 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -55,6 +55,70 @@ static inline void mesh_plink_fsm_restart(struct sta_info *sta)
sta->plink_retries = 0;
}
+/*
+ * mesh_set_short_slot_time - enable / disable ERP short slot time.
+ *
+ * The standard indirectly mandates mesh STAs to turn off short slot time by
+ * disallowing advertising this (802.11-2012 8.4.1.4), but that doesn't mean we
+ * can't be sneaky about it. Enable short slot time if all mesh STAs in the
+ * MBSS support ERP rates.
+ *
+ * Returns BSS_CHANGED_ERP_SLOT or 0 for no change.
+ */
+static u32 mesh_set_short_slot_time(struct ieee80211_sub_if_data *sdata)
+{
+ struct ieee80211_local *local = sdata->local;
+ enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
+ struct ieee80211_rate *bitrates;
+ struct ieee80211_supported_band *sband;
+ struct sta_info *sta;
+ u32 rates, changed = 0;
+ int i;
+ bool short_slot = false;
+
+ if (band == IEEE80211_BAND_5GHZ) {
+ /* (IEEE 802.11-2012 19.4.5) */
+ short_slot = true;
+ goto out;
+ } else if (band != IEEE80211_BAND_2GHZ ||
+ (band == IEEE80211_BAND_2GHZ &&
+ local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE))
+ goto out;
+
+ sband = local->hw.wiphy->bands[band];
+ bitrates = sband->bitrates;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(sta, &local->sta_list, list) {
+ if (sdata != sta->sdata ||
+ sta->plink_state != NL80211_PLINK_ESTAB)
+ continue;
+
+ short_slot = false;
+ rates = sta->sta.supp_rates[band];
+ for_each_set_bit(i, (unsigned long *)&rates,
+ sizeof(rates) * BITS_PER_BYTE) {
+ if (bitrates[i].flags & IEEE80211_RATE_ERP_G) {
+ short_slot = true;
+ break;
+ }
+ }
+
+ if (!short_slot)
+ break;
+ }
+ rcu_read_unlock();
+
+out:
+ if (sdata->vif.bss_conf.use_short_slot != short_slot) {
+ sdata->vif.bss_conf.use_short_slot = short_slot;
+ changed = BSS_CHANGED_ERP_SLOT;
+ mpl_dbg(sdata, "mesh_plink %pM: ERP short slot time %d\n",
+ sdata->vif.addr, short_slot);
+ }
+ return changed;
+}
+
/**
* mesh_set_ht_prot_mode - set correct HT protection mode
*
@@ -894,6 +958,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
spin_unlock_bh(&sta->lock);
changed |= mesh_plink_inc_estab_count(sdata);
changed |= mesh_set_ht_prot_mode(sdata);
+ changed |= mesh_set_short_slot_time(sdata);
mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n",
sta->sta.addr);
break;
@@ -929,6 +994,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
spin_unlock_bh(&sta->lock);
changed |= mesh_plink_inc_estab_count(sdata);
changed |= mesh_set_ht_prot_mode(sdata);
+ changed |= mesh_set_short_slot_time(sdata);
mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n",
sta->sta.addr);
mesh_plink_frame_tx(sdata,
@@ -952,6 +1018,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
spin_unlock_bh(&sta->lock);
changed |= mesh_set_ht_prot_mode(sdata);
+ changed |= mesh_set_short_slot_time(sdata);
mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
sta->sta.addr, llid, plid, reason);
break;
--
1.7.10.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v2] mac80211: dynamic short slot time for MBSSs
2013-01-26 20:37 [PATCH v2] mac80211: dynamic short slot time for MBSSs Thomas Pedersen
@ 2013-01-26 22:58 ` Johannes Berg
2013-01-26 23:05 ` Johannes Berg
2013-01-26 23:04 ` Johannes Berg
1 sibling, 1 reply; 6+ messages in thread
From: Johannes Berg @ 2013-01-26 22:58 UTC (permalink / raw)
To: Thomas Pedersen; +Cc: linux-wireless, devel
On Sat, 2013-01-26 at 12:37 -0800, Thomas Pedersen wrote:
> + u32 rates, changed = 0;
> + for_each_set_bit(i, (unsigned long *)&rates,
> + sizeof(rates) * BITS_PER_BYTE) {
this is broken on 64-bit architectures.
johannes
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] mac80211: dynamic short slot time for MBSSs
2013-01-26 20:37 [PATCH v2] mac80211: dynamic short slot time for MBSSs Thomas Pedersen
2013-01-26 22:58 ` Johannes Berg
@ 2013-01-26 23:04 ` Johannes Berg
2013-01-26 23:36 ` Thomas Pedersen
1 sibling, 1 reply; 6+ messages in thread
From: Johannes Berg @ 2013-01-26 23:04 UTC (permalink / raw)
To: Thomas Pedersen; +Cc: linux-wireless, devel
> + sband = local->hw.wiphy->bands[band];
> + bitrates = sband->bitrates;
It might be interesting to loop once here and build a bitmap (in an
unsigned long) of rates marked ERP_G. Something like
erp_rates = 0;
for (i = 0; i < sband->n_bitrates; i++)
if (bitrates[i].flags & ...)
erp_rates |= BIT(i);
> + rcu_read_lock();
> + list_for_each_entry_rcu(sta, &local->sta_list, list) {
> + if (sdata != sta->sdata ||
> + sta->plink_state != NL80211_PLINK_ESTAB)
> + continue;
> +
> + short_slot = false;
> + rates = sta->sta.supp_rates[band];
> + for_each_set_bit(i, (unsigned long *)&rates,
> + sizeof(rates) * BITS_PER_BYTE) {
> + if (bitrates[i].flags & IEEE80211_RATE_ERP_G) {
> + short_slot = true;
> + break;
> + }
> + }
> +
> + if (!short_slot)
> + break;
Then the inner bitrate loop here becomes just
if (!(rates & erp_rates)) {
short_slot = false;
break;
}
which assumes "short_slot = true" as a precondition to going into the
sta loop.
(although that does change the overall logic to enable short slot when
NO stations are present)
johannes
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] mac80211: dynamic short slot time for MBSSs
2013-01-26 22:58 ` Johannes Berg
@ 2013-01-26 23:05 ` Johannes Berg
0 siblings, 0 replies; 6+ messages in thread
From: Johannes Berg @ 2013-01-26 23:05 UTC (permalink / raw)
To: Thomas Pedersen; +Cc: linux-wireless, devel
On Sat, 2013-01-26 at 23:58 +0100, Johannes Berg wrote:
> On Sat, 2013-01-26 at 12:37 -0800, Thomas Pedersen wrote:
>
> > + u32 rates, changed = 0;
>
> > + for_each_set_bit(i, (unsigned long *)&rates,
> > + sizeof(rates) * BITS_PER_BYTE) {
>
> this is broken on 64-bit architectures.
Actually, probably only on big endian 64-bit architectures.
johannes
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] mac80211: dynamic short slot time for MBSSs
2013-01-26 23:04 ` Johannes Berg
@ 2013-01-26 23:36 ` Thomas Pedersen
2013-01-26 23:48 ` Johannes Berg
0 siblings, 1 reply; 6+ messages in thread
From: Thomas Pedersen @ 2013-01-26 23:36 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, devel
On Sat, Jan 26, 2013 at 3:04 PM, Johannes Berg
<johannes@sipsolutions.net> wrote:
>
>> + sband = local->hw.wiphy->bands[band];
>> + bitrates = sband->bitrates;
>
> It might be interesting to loop once here and build a bitmap (in an
> unsigned long) of rates marked ERP_G. Something like
>
> erp_rates = 0;
> for (i = 0; i < sband->n_bitrates; i++)
> if (bitrates[i].flags & ...)
> erp_rates |= BIT(i);
>
>
>> + rcu_read_lock();
>> + list_for_each_entry_rcu(sta, &local->sta_list, list) {
>> + if (sdata != sta->sdata ||
>> + sta->plink_state != NL80211_PLINK_ESTAB)
>> + continue;
>> +
>> + short_slot = false;
>> + rates = sta->sta.supp_rates[band];
>> + for_each_set_bit(i, (unsigned long *)&rates,
>> + sizeof(rates) * BITS_PER_BYTE) {
>> + if (bitrates[i].flags & IEEE80211_RATE_ERP_G) {
>> + short_slot = true;
>> + break;
>> + }
>> + }
>> +
>> + if (!short_slot)
>> + break;
>
> Then the inner bitrate loop here becomes just
>
> if (!(rates & erp_rates)) {
> short_slot = false;
> break;
> }
Huh, that's actually pretty nice. I don't really get why the
for_each_set_bit() is broken on big endian 64-bit systems, but hey
this approach takes care of that concern :)
> which assumes "short_slot = true" as a precondition to going into the
> sta loop.
>
> (although that does change the overall logic to enable short slot when
> NO stations are present)
Sure. We'll disable it when not locally supported anyway.
Thanks.
--
Thomas
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2] mac80211: dynamic short slot time for MBSSs
2013-01-26 23:36 ` Thomas Pedersen
@ 2013-01-26 23:48 ` Johannes Berg
0 siblings, 0 replies; 6+ messages in thread
From: Johannes Berg @ 2013-01-26 23:48 UTC (permalink / raw)
To: Thomas Pedersen; +Cc: linux-wireless, devel
On Sat, 2013-01-26 at 15:36 -0800, Thomas Pedersen wrote:
> Huh, that's actually pretty nice.
:)
> I don't really get why the
> for_each_set_bit() is broken on big endian 64-bit systems, but hey
> this approach takes care of that concern :)
Because then you're taking the address of a 32-bit variable, and
treating it as an unsigned long (64 bits), so if you iterate its 64 bits
then you'll get some random other stuff from the stack (on both big and
little endian actually, I thought you were limiting it to n_bitrates
then it would work on little endian)
johannes
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2013-01-26 23:48 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-01-26 20:37 [PATCH v2] mac80211: dynamic short slot time for MBSSs Thomas Pedersen
2013-01-26 22:58 ` Johannes Berg
2013-01-26 23:05 ` Johannes Berg
2013-01-26 23:04 ` Johannes Berg
2013-01-26 23:36 ` Thomas Pedersen
2013-01-26 23:48 ` Johannes Berg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox