wifi: cfg80211: send MLO links tx power info in GET_INTERFACE

Currently, TX power is reported on interface/wdev level as
part of NL80211_CMD_GET_INTERFACE. With MLO, Multiple links
can be part of an interface/wdev and hence its necessary to
report the TX power of each link.

Add support to send tx power for all valid links of an MLD as
part of NL80211_CMD_GET_INTERFACE request.

As far as userspace is concerned, there is no behavioral change
for Non-ML Interfaces. For ML interfaces, userspace should fetch
TX power that is nested inside NL80211_ATTR_MLO_LINKS, similar to
how channel info(NL80211_ATTR_WIPHY_FREQ) is fetched.

Co-developed-by: Aaradhana Sahu <quic_aarasahu@quicinc.com>
Signed-off-by: Aaradhana Sahu <quic_aarasahu@quicinc.com>
Signed-off-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
Link: https://patch.msgid.link/20241125083217.216095-2-quic_ramess@quicinc.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Rameshkumar Sundaram 2024-11-25 14:02:16 +05:30 committed by Johannes Berg
parent 4e3a841c47
commit 7a53af85d3
12 changed files with 47 additions and 34 deletions

View File

@ -1441,6 +1441,7 @@ static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy,
struct wireless_dev *wdev,
unsigned int link_id,
int *dbm)
{
struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);

View File

@ -2676,7 +2676,7 @@ done:
static s32
brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
s32 *dbm)
unsigned int link_id, s32 *dbm)
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_cfg80211_vif *vif = wdev_to_vif(wdev);

View File

@ -410,7 +410,7 @@ mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy,
static int
mwifiex_cfg80211_get_tx_power(struct wiphy *wiphy,
struct wireless_dev *wdev,
int *dbm)
unsigned int link_id, int *dbm)
{
struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
struct mwifiex_private *priv = mwifiex_get_priv(adapter,

View File

@ -1669,7 +1669,7 @@ static int set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
}
static int get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
int *dbm)
unsigned int link_id, int *dbm)
{
int ret;
struct wilc_vif *vif = netdev_priv(wdev->netdev);

View File

@ -881,7 +881,7 @@ static int qtnf_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
}
static int qtnf_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
int *dbm)
unsigned int link_id, int *dbm)
{
struct qtnf_vif *vif = qtnf_netdev_get_priv(wdev->netdev);
int ret;

View File

@ -1802,7 +1802,8 @@ static int cfg80211_rtw_set_txpower(struct wiphy *wiphy,
}
static int cfg80211_rtw_get_txpower(struct wiphy *wiphy,
struct wireless_dev *wdev, int *dbm)
struct wireless_dev *wdev,
unsigned int link_id, int *dbm)
{
*dbm = (12);

View File

@ -4733,7 +4733,7 @@ struct cfg80211_ops {
int (*set_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev,
enum nl80211_tx_power_setting type, int mbm);
int (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev,
int *dbm);
unsigned int link_id, int *dbm);
void (*rfkill_poll)(struct wiphy *wiphy);

View File

@ -3190,6 +3190,7 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
static int ieee80211_get_tx_power(struct wiphy *wiphy,
struct wireless_dev *wdev,
unsigned int link_id,
int *dbm)
{
struct ieee80211_local *local = wiphy_priv(wiphy);

View File

@ -3980,10 +3980,10 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag
goto nla_put_failure;
}
if (rdev->ops->get_tx_power) {
if (rdev->ops->get_tx_power && !wdev->valid_links) {
int dbm, ret;
ret = rdev_get_tx_power(rdev, wdev, &dbm);
ret = rdev_get_tx_power(rdev, wdev, 0, &dbm);
if (ret == 0 &&
nla_put_u32(msg, NL80211_ATTR_WIPHY_TX_POWER_LEVEL,
DBM_TO_MBM(dbm)))
@ -4052,6 +4052,15 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag
if (ret == 0 && nl80211_send_chandef(msg, &chandef))
goto nla_put_failure;
if (rdev->ops->get_tx_power) {
int dbm, ret;
ret = rdev_get_tx_power(rdev, wdev, link_id, &dbm);
if (ret == 0 &&
nla_put_u32(msg, NL80211_ATTR_WIPHY_TX_POWER_LEVEL,
DBM_TO_MBM(dbm)))
goto nla_put_failure;
}
nla_nest_end(msg, link);
}

View File

@ -600,11 +600,12 @@ static inline int rdev_set_tx_power(struct cfg80211_registered_device *rdev,
}
static inline int rdev_get_tx_power(struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev, int *dbm)
struct wireless_dev *wdev, unsigned int link_id,
int *dbm)
{
int ret;
trace_rdev_get_tx_power(&rdev->wiphy, wdev);
ret = rdev->ops->get_tx_power(&rdev->wiphy, wdev, dbm);
trace_rdev_get_tx_power(&rdev->wiphy, wdev, link_id);
ret = rdev->ops->get_tx_power(&rdev->wiphy, wdev, link_id, dbm);
trace_rdev_return_int_int(&rdev->wiphy, ret, *dbm);
return ret;
}

View File

@ -1690,9 +1690,28 @@ TRACE_EVENT(rdev_set_wiphy_params,
WIPHY_PR_ARG, __entry->changed)
);
DEFINE_EVENT(wiphy_wdev_evt, rdev_get_tx_power,
TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev),
TP_ARGS(wiphy, wdev)
DECLARE_EVENT_CLASS(wiphy_wdev_link_evt,
TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
unsigned int link_id),
TP_ARGS(wiphy, wdev, link_id),
TP_STRUCT__entry(
WIPHY_ENTRY
WDEV_ENTRY
__field(unsigned int, link_id)
),
TP_fast_assign(
WIPHY_ASSIGN;
WDEV_ASSIGN;
__entry->link_id = link_id;
),
TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", link_id: %u",
WIPHY_PR_ARG, WDEV_PR_ARG, __entry->link_id)
);
DEFINE_EVENT(wiphy_wdev_link_evt, rdev_get_tx_power,
TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
unsigned int link_id),
TP_ARGS(wiphy, wdev, link_id)
);
TRACE_EVENT(rdev_set_tx_power,
@ -2192,25 +2211,6 @@ TRACE_EVENT(rdev_set_noack_map,
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", noack_map: %u",
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->noack_map)
);
DECLARE_EVENT_CLASS(wiphy_wdev_link_evt,
TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
unsigned int link_id),
TP_ARGS(wiphy, wdev, link_id),
TP_STRUCT__entry(
WIPHY_ENTRY
WDEV_ENTRY
__field(unsigned int, link_id)
),
TP_fast_assign(
WIPHY_ASSIGN;
WDEV_ASSIGN;
__entry->link_id = link_id;
),
TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", link_id: %u",
WIPHY_PR_ARG, WDEV_PR_ARG, __entry->link_id)
);
DEFINE_EVENT(wiphy_wdev_link_evt, rdev_get_channel,
TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
unsigned int link_id),

View File

@ -910,7 +910,7 @@ static int cfg80211_wext_giwtxpower(struct net_device *dev,
return -EOPNOTSUPP;
scoped_guard(wiphy, &rdev->wiphy) {
err = rdev_get_tx_power(rdev, wdev, &val);
err = rdev_get_tx_power(rdev, wdev, 0, &val);
}
if (err)
return err;