diff options
author | Felix Fietkau <nbd@nbd.name> | 2024-10-09 10:25:48 +0200 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2024-10-23 16:45:43 +0200 |
commit | 9d40f7e32774279be7e5a7a278d7a290872b2f81 (patch) | |
tree | aadb47a404a624a58c6f8877e1a066a82c05ee21 /net/mac80211/util.c | |
parent | 9c4f830927750a2bf9fd9426a5257f0fdce3b662 (diff) |
wifi: mac80211: add flag to opt out of virtual monitor support
This is useful for multi-radio devices that are capable of monitoring on
multiple channels simultanenously. When this flag is set, each monitor
interface is passed to the driver individually and can have a configured
channel.
The vif mac address for non-active monitor interfaces is cleared, in order
to allow the driver to tell them apart from active ones.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Link: https://patch.msgid.link/3c55505ee0cf0a5f141fbcb30d1e8be8d9f40373.1728462320.git-series.nbd@nbd.name
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r-- | net/mac80211/util.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index bd93de637f94..a4e1301cc999 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -756,7 +756,8 @@ static void __iterate_interfaces(struct ieee80211_local *local, lockdep_is_held(&local->hw.wiphy->mtx)) { switch (sdata->vif.type) { case NL80211_IFTYPE_MONITOR: - if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE)) + if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) && + !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) continue; break; case NL80211_IFTYPE_AP_VLAN: @@ -1873,8 +1874,10 @@ int ieee80211_reconfig(struct ieee80211_local *local) } list_for_each_entry(sdata, &local->interfaces, list) { + if (sdata->vif.type == NL80211_IFTYPE_MONITOR && + !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) + continue; if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && - sdata->vif.type != NL80211_IFTYPE_MONITOR && ieee80211_sdata_running(sdata)) { res = drv_add_interface(local, sdata); if (WARN_ON(res)) @@ -1887,11 +1890,14 @@ int ieee80211_reconfig(struct ieee80211_local *local) */ if (res) { list_for_each_entry_continue_reverse(sdata, &local->interfaces, - list) + list) { + if (sdata->vif.type == NL80211_IFTYPE_MONITOR && + !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) + continue; if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && - sdata->vif.type != NL80211_IFTYPE_MONITOR && ieee80211_sdata_running(sdata)) drv_remove_interface(local, sdata); + } ieee80211_handle_reconfig_failure(local); return res; } |