wifi: mac80211_hwsim: report TX status link_id

Populate link_valid/link_id in mac80211_hwsim TX status so the
transmitted link is reported to mac80211.

Set the link information in both the direct TX status path and the
wmediumd/netlink TX status path.

With that done, enable NL80211_EXT_FEATURE_PROBE_AP.

Signed-off-by: Priyansha Tiwari <priyansha.tiwari@oss.qualcomm.com>
Link: https://patch.msgid.link/20260709114228.672317-3-pritiwa@qti.qualcomm.com
[add note about NL80211_EXT_FEATURE_PROBE_AP]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Priyansha Tiwari 2026-07-09 17:12:28 +05:30 committed by Johannes Berg
parent 1c3f880ed0
commit f153501041

View File

@ -2103,6 +2103,7 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
bool ack, unicast_data;
enum nl80211_chan_width confbw = NL80211_CHAN_WIDTH_20_NOHT;
u32 _portid, i;
int tx_link_id = -1;
if (WARN_ON(skb->len < 10)) {
/* Should not happen; just a sanity check for addr1 use */
@ -2160,6 +2161,9 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
hdr, &link_sta);
}
if (bss_conf)
tx_link_id = bss_conf->link_id;
if (unlikely(!bss_conf)) {
/* if it's an MLO STA, it might have deactivated all
* links temporarily - but we don't handle real PS in
@ -2271,6 +2275,12 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw,
if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK) && ack)
txi->flags |= IEEE80211_TX_STAT_ACK;
if (tx_link_id >= 0) {
txi->status.link_valid = 1;
txi->status.link_id = tx_link_id;
}
ieee80211_tx_status_irqsafe(hw, skb);
}
@ -6106,6 +6116,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_PUNCT);
wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_PROBE_AP);
for (i = 0; i < ARRAY_SIZE(data->link_data); i++) {
hrtimer_setup(&data->link_data[i].beacon_timer, mac80211_hwsim_beacon,
@ -6333,6 +6344,27 @@ static void hwsim_register_wmediumd(struct net *net, u32 portid)
spin_unlock_bh(&hwsim_radio_lock);
}
static int mac80211_hwsim_get_link_id(struct ieee80211_vif *vif,
struct ieee80211_hdr *hdr)
{
int i;
if (!vif || !ieee80211_vif_is_mld(vif))
return -1;
for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) {
struct ieee80211_bss_conf *link_conf;
link_conf = rcu_dereference(vif->link_conf[i]);
if (!link_conf)
continue;
if (ether_addr_equal(link_conf->addr, hdr->addr2))
return i;
}
return -1;
}
static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
struct genl_info *info)
{
@ -6413,13 +6445,18 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
txi->status.ack_signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]);
hdr = (struct ieee80211_hdr *)skb->data;
i = mac80211_hwsim_get_link_id(txi->control.vif, hdr);
if (i >= 0) {
txi->status.link_valid = 1;
txi->status.link_id = i;
}
if (!(hwsim_flags & HWSIM_TX_CTL_NO_ACK) &&
(hwsim_flags & HWSIM_TX_STAT_ACK)) {
if (skb->len >= 16) {
hdr = (struct ieee80211_hdr *) skb->data;
if (skb->len >= 16)
mac80211_hwsim_monitor_ack(data2->channel,
hdr->addr2);
}
txi->flags |= IEEE80211_TX_STAT_ACK;
}