summaryrefslogtreecommitdiff
path: root/net/mac80211/cfg.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r--net/mac80211/cfg.c47
1 files changed, 32 insertions, 15 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index c52b0456039d..b51c2c8584ae 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -63,12 +63,14 @@ static void ieee80211_set_mu_mimo_follow(struct ieee80211_sub_if_data *sdata,
memcpy(sdata->vif.bss_conf.mu_group.position,
params->vht_mumimo_groups + WLAN_MEMBERSHIP_LEN,
WLAN_USER_POSITION_LEN);
- ieee80211_link_info_change_notify(sdata, &sdata->deflink,
- BSS_CHANGED_MU_GROUPS);
+
/* don't care about endianness - just check for 0 */
memcpy(&membership, params->vht_mumimo_groups,
WLAN_MEMBERSHIP_LEN);
mu_mimo_groups = membership != 0;
+
+ /* Unset following if configured explicitly */
+ eth_broadcast_addr(sdata->u.mntr.mu_follow_addr);
}
if (params->vht_mumimo_follow_addr) {
@@ -76,16 +78,26 @@ static void ieee80211_set_mu_mimo_follow(struct ieee80211_sub_if_data *sdata,
is_valid_ether_addr(params->vht_mumimo_follow_addr);
ether_addr_copy(sdata->u.mntr.mu_follow_addr,
params->vht_mumimo_follow_addr);
+
+ /* Unset current membership until a management frame is RXed */
+ memset(sdata->vif.bss_conf.mu_group.membership, 0,
+ WLAN_MEMBERSHIP_LEN);
}
sdata->vif.bss_conf.mu_mimo_owner = mu_mimo_groups || mu_mimo_follow;
+
+ /* Notify only after setting mu_mimo_owner */
+ if (sdata->vif.bss_conf.mu_mimo_owner &&
+ sdata->flags & IEEE80211_SDATA_IN_DRIVER)
+ ieee80211_link_info_change_notify(sdata, &sdata->deflink,
+ BSS_CHANGED_MU_GROUPS);
}
static int ieee80211_set_mon_options(struct ieee80211_sub_if_data *sdata,
struct vif_params *params)
{
struct ieee80211_local *local = sdata->local;
- struct ieee80211_sub_if_data *monitor_sdata;
+ struct ieee80211_sub_if_data *monitor_sdata = NULL;
/* check flags first */
if (params->flags && ieee80211_sdata_running(sdata)) {
@@ -103,23 +115,28 @@ static int ieee80211_set_mon_options(struct ieee80211_sub_if_data *sdata,
return -EBUSY;
}
- /* also validate MU-MIMO change */
- if (ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR))
- monitor_sdata = sdata;
- else
- monitor_sdata = wiphy_dereference(local->hw.wiphy,
- local->monitor_sdata);
-
- if (!monitor_sdata &&
+ /* validate whether MU-MIMO can be configured */
+ if (!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF) &&
+ !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR) &&
(params->vht_mumimo_groups || params->vht_mumimo_follow_addr))
return -EOPNOTSUPP;
+ /* Also update dependent monitor_sdata if required */
+ if (test_bit(SDATA_STATE_RUNNING, &sdata->state) &&
+ !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR))
+ monitor_sdata = wiphy_dereference(local->hw.wiphy,
+ local->monitor_sdata);
+
/* apply all changes now - no failures allowed */
- if (monitor_sdata &&
- (ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF) ||
- ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)))
- ieee80211_set_mu_mimo_follow(monitor_sdata, params);
+ if (ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF) ||
+ ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) {
+ /* This is copied in when the VIF is activated */
+ ieee80211_set_mu_mimo_follow(sdata, params);
+
+ if (monitor_sdata)
+ ieee80211_set_mu_mimo_follow(monitor_sdata, params);
+ }
if (params->flags) {
if (ieee80211_sdata_running(sdata)) {