wlan-ap-Telecominfraproject/feeds/ipq95xx/mac80211/patches/qca/703-02-mac80211-add-support-for-set-link-specific-tx-power.patch
John Crispin 144c5d00f4 ipq95xx/mac80211: update to ATH12.3-CS
Signed-off-by: John Crispin <john@phrozen.org>
2024-02-28 18:56:21 +01:00

250 lines
8.3 KiB
Diff

From f689bf1cf18b473e82deab670a04064c2ce0db32 Mon Sep 17 00:00:00 2001
From: Aaradhana Sahu <quic_aarasahu@quicinc.com>
Date: Fri, 16 Dec 2022 15:58:50 +0530
Subject: [PATCH] mac80211: add support for set link specific tx power
Currently, we set tx power form user space according to
phy and each phy has particular band and tx power,but
in multi-link operation each phy has more than one
link and each link is working on different band, tx power.
So, add support set tx power according to link id.
Signed-off-by: Aaradhana Sahu <quic_aarasahu@quicinc.com>
---
net/mac80211/cfg.c | 24 ++++++++++++++---------
net/mac80211/chan.c | 4 ++--
net/mac80211/ieee80211_i.h | 5 +++--
net/mac80211/iface.c | 39 +++++++++++++++++++++++++-------------
net/mac80211/link.c | 4 ++++
net/mac80211/mlme.c | 2 +-
6 files changed, 51 insertions(+), 27 deletions(-)
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -3071,17 +3071,23 @@ static int ieee80211_set_wiphy_params(st
static int ieee80211_set_tx_power(struct wiphy *wiphy,
struct wireless_dev *wdev,
- enum nl80211_tx_power_setting type, int mbm)
+ enum nl80211_tx_power_setting type,
+ int mbm, unsigned int link_id)
{
struct ieee80211_local *local = wiphy_priv(wiphy);
struct ieee80211_sub_if_data *sdata;
enum nl80211_tx_power_setting txp_type = type;
bool update_txp_type = false;
bool has_monitor = false;
+ struct ieee80211_link_data *link_data;
if (wdev) {
sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
+ link_data = sdata_dereference(sdata->link[link_id], sdata);
+ if (!link_data)
+ return -ENOLINK;
+
if (sdata->vif.type == NL80211_IFTYPE_MONITOR) {
sdata = wiphy_dereference(local->hw.wiphy,
local->monitor_sdata);
@@ -3091,7 +3097,7 @@ static int ieee80211_set_tx_power(struct
switch (type) {
case NL80211_TX_POWER_AUTOMATIC:
- sdata->deflink.user_power_level =
+ link_data->user_power_level =
IEEE80211_UNSET_POWER_LEVEL;
txp_type = NL80211_TX_POWER_LIMITED;
break;
@@ -3099,16 +3105,16 @@ static int ieee80211_set_tx_power(struct
case NL80211_TX_POWER_FIXED:
if (mbm < 0 || (mbm % 100))
return -EOPNOTSUPP;
- sdata->deflink.user_power_level = MBM_TO_DBM(mbm);
+ link_data->user_power_level = MBM_TO_DBM(mbm);
break;
}
- if (txp_type != sdata->vif.bss_conf.txpower_type) {
+ if (txp_type != link_data->conf->txpower_type) {
update_txp_type = true;
- sdata->vif.bss_conf.txpower_type = txp_type;
+ link_data->conf->txpower_type = txp_type;
}
- ieee80211_recalc_txpower(sdata, update_txp_type);
+ ieee80211_recalc_txpower(sdata, update_txp_type, link_id);
return 0;
}
@@ -3126,6 +3132,7 @@ static int ieee80211_set_tx_power(struct
break;
}
+ /*TODO: monitor mode for MLO */
mutex_lock(&local->iflist_mtx);
list_for_each_entry(sdata, &local->interfaces, list) {
if (sdata->vif.type == NL80211_IFTYPE_MONITOR) {
@@ -3140,7 +3147,7 @@ static int ieee80211_set_tx_power(struct
list_for_each_entry(sdata, &local->interfaces, list) {
if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
continue;
- ieee80211_recalc_txpower(sdata, update_txp_type);
+ ieee80211_recalc_txpower(sdata, update_txp_type, link_id);
}
mutex_unlock(&local->iflist_mtx);
@@ -3153,7 +3160,7 @@ static int ieee80211_set_tx_power(struct
update_txp_type = true;
sdata->vif.bss_conf.txpower_type = txp_type;
- ieee80211_recalc_txpower(sdata, update_txp_type);
+ ieee80211_recalc_txpower(sdata, update_txp_type, 0);
}
}
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -899,7 +899,7 @@ out:
}
if (new_ctx && ieee80211_chanctx_num_assigned(local, new_ctx) > 0) {
- ieee80211_recalc_txpower(sdata, false);
+ ieee80211_recalc_txpower(sdata, false, link->link_id);
ieee80211_recalc_chanctx_min_def(local, new_ctx);
}
@@ -1686,7 +1686,7 @@ static int ieee80211_vif_use_reserved_sw
link,
changed);
- ieee80211_recalc_txpower(sdata, false);
+ ieee80211_recalc_txpower(sdata, false, link->link_id);
}
ieee80211_recalc_chanctx_chantype(local, ctx);
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1983,9 +1983,10 @@ void ieee80211_sdata_stop(struct ieee802
int ieee80211_add_virtual_monitor(struct ieee80211_local *local);
void ieee80211_del_virtual_monitor(struct ieee80211_local *local);
-bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata);
+bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata,
+ unsigned int link_id);
void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata,
- bool update_bss);
+ bool update_bss, unsigned int link_id);
void ieee80211_recalc_offload(struct ieee80211_local *local);
static inline bool ieee80211_sdata_running(struct ieee80211_sub_if_data *sdata)
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -57,13 +57,20 @@ MODULE_PARM_DESC(ppe_vp_accel, "module p
static void ieee80211_iface_work(struct work_struct *work);
-bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
+bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata,
+ unsigned int link_id)
{
struct ieee80211_chanctx_conf *chanctx_conf;
int power;
+ struct ieee80211_link_data *link_data;
+
+ link_data = sdata_dereference(sdata->link[link_id], sdata);
+ if (!link_data)
+ return false;
rcu_read_lock();
- chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
+
+ chanctx_conf = rcu_dereference(link_data->conf->chanctx_conf);
if (!chanctx_conf) {
rcu_read_unlock();
return false;
@@ -72,14 +79,14 @@ bool __ieee80211_recalc_txpower(struct i
power = ieee80211_chandef_max_power(&chanctx_conf->def);
rcu_read_unlock();
- if (sdata->deflink.user_power_level != IEEE80211_UNSET_POWER_LEVEL)
- power = min(power, sdata->deflink.user_power_level);
+ if (link_data->user_power_level != IEEE80211_UNSET_POWER_LEVEL)
+ power = min(power, link_data->user_power_level);
- if (sdata->deflink.ap_power_level != IEEE80211_UNSET_POWER_LEVEL)
- power = min(power, sdata->deflink.ap_power_level);
+ if (link_data->ap_power_level != IEEE80211_UNSET_POWER_LEVEL)
+ power = min(power, link_data->ap_power_level);
- if (power != sdata->vif.bss_conf.txpower) {
- sdata->vif.bss_conf.txpower = power;
+ if (power != link_data->conf->txpower) {
+ link_data->conf->txpower = power;
ieee80211_hw_config(sdata->local, 0);
return true;
}
@@ -88,12 +95,19 @@ bool __ieee80211_recalc_txpower(struct i
}
void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata,
- bool update_bss)
+ bool update_bss, unsigned int link_id)
{
- if (__ieee80211_recalc_txpower(sdata) ||
- (update_bss && ieee80211_sdata_running(sdata)))
- ieee80211_link_info_change_notify(sdata, &sdata->deflink,
+ if (__ieee80211_recalc_txpower(sdata, link_id) ||
+ (update_bss && ieee80211_sdata_running(sdata))) {
+ struct ieee80211_link_data *link_data;
+
+ link_data = sdata_dereference(sdata->link[link_id], sdata);
+ if (!link_data)
+ return;
+
+ ieee80211_link_info_change_notify(sdata, link_data,
BSS_CHANGED_TXPOWER);
+ }
}
static u32 __ieee80211_idle_off(struct ieee80211_local *local)
@@ -2316,7 +2330,6 @@ int ieee80211_if_add(struct ieee80211_lo
sdata->deflink.ap_power_level = IEEE80211_UNSET_POWER_LEVEL;
sdata->deflink.user_power_level = local->user_power_level;
-
/* setup type-dependent data */
ieee80211_setup_sdata(sdata, type);
--- a/net/mac80211/link.c
+++ b/net/mac80211/link.c
@@ -21,6 +21,7 @@ void ieee80211_link_init(struct ieee8021
struct ieee80211_link_data *link,
struct ieee80211_bss_conf *link_conf)
{
+ struct ieee80211_local *local = sdata->local;
bool deflink = link_id < 0;
if (link_id < 0)
@@ -43,6 +44,9 @@ void ieee80211_link_init(struct ieee8021
INIT_DELAYED_WORK(&link->dfs_cac_timer_work,
ieee80211_dfs_cac_timer_work);
+ link->ap_power_level = IEEE80211_UNSET_POWER_LEVEL;
+ link->user_power_level = local->user_power_level;
+
if (!deflink) {
switch (sdata->vif.type) {
case NL80211_IFTYPE_AP:
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2095,7 +2095,7 @@ static u32 ieee80211_handle_pwr_constr(s
}
link->ap_power_level = new_ap_level;
- if (__ieee80211_recalc_txpower(sdata))
+ if (__ieee80211_recalc_txpower(sdata, 0))
return BSS_CHANGED_TXPOWER;
return 0;
}