Configure per packet Transmit Power Control (TPC) in lower drivers checking if user_power_level has been set to IEEE80211_UNSET_POWER_LEVEL Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi83@xxxxxxxxx> --- include/net/mac80211.h | 5 +++++ net/mac80211/iface.c | 7 ++++++- net/mac80211/main.c | 8 +++++++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index cff3a26..233626d 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -376,6 +376,7 @@ enum ieee80211_rssi_event { * @ssid_len: Length of SSID given in @ssid. * @hidden_ssid: The SSID of the current vif is hidden. Only valid in AP-mode. * @txpower: TX power in dBm + * @tpc_enabled: enable/disable per packet Transmit Power Control (TPC) * @p2p_noa_attr: P2P NoA attribute for P2P powersave */ struct ieee80211_bss_conf { @@ -411,6 +412,7 @@ struct ieee80211_bss_conf { size_t ssid_len; bool hidden_ssid; int txpower; + bool tpc_enabled; struct ieee80211_p2p_noa_attr p2p_noa_attr; }; @@ -1115,6 +1117,8 @@ enum ieee80211_smps_mode { * * @power_level: requested transmit power (in dBm), backward compatibility * value only that is set to the minimum of all interfaces + * @tpc_enabled: enable/disable per packet Transmit Power Control (TPC) in + * lower driver * * @chandef: the channel definition to tune to * @radar_enabled: whether radar detection is enabled @@ -1135,6 +1139,7 @@ enum ieee80211_smps_mode { struct ieee80211_conf { u32 flags; int power_level, dynamic_ps_timeout; + bool tpc_enabled; int max_sleep_period; u16 listen_interval; diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 538fe4e..70c94a3 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -47,6 +47,7 @@ bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata) { struct ieee80211_chanctx_conf *chanctx_conf; int power; + bool tpc_enabled; rcu_read_lock(); chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); @@ -64,8 +65,12 @@ bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata) if (sdata->ap_power_level != IEEE80211_UNSET_POWER_LEVEL) power = min(power, sdata->ap_power_level); - if (power != sdata->vif.bss_conf.txpower) { + tpc_enabled = (sdata->user_power_level == IEEE80211_UNSET_POWER_LEVEL); + + if (power != sdata->vif.bss_conf.txpower || + tpc_enabled != sdata->vif.bss_conf.tpc_enabled) { sdata->vif.bss_conf.txpower = power; + sdata->vif.bss_conf.tpc_enabled = tpc_enabled; ieee80211_hw_config(sdata->local, 0); return true; } diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 6ab99da..bfcaeee 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -100,6 +100,7 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local) u32 changed = 0; int power; u32 offchannel_flag; + bool tpc_enabled = false; offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; @@ -152,12 +153,17 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local) if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) continue; power = min(power, sdata->vif.bss_conf.txpower); + + if (!tpc_enabled && sdata->vif.bss_conf.tpc_enabled) + tpc_enabled = true; } rcu_read_unlock(); - if (local->hw.conf.power_level != power) { + if (local->hw.conf.power_level != power || + local->hw.conf.tpc_enabled != tpc_enabled) { changed |= IEEE80211_CONF_CHANGE_POWER; local->hw.conf.power_level = power; + local->hw.conf.tpc_enabled = tpc_enabled; } return changed; -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html