mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-20 19:03:39 +00:00
250 lines
8.3 KiB
Diff
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;
|
|
}
|