From 5fcc7c51f9e72d1e62991f8b32be4a5adf44d556 Mon Sep 17 00:00:00 2001 From: Aditya Kumar Singh Date: Tue, 27 Feb 2024 09:52:51 +0530 Subject: wifi: mac80211: handle netif carrier up/down with link AP during MLO Currently whenever link AP is started, netif_carrier_up() function is called and whenever it is brought down, netif_carrier_down() function is called. However, with MLO, all the links of the same MLD would use the same netdev. Hence there is no need to indicate for each link up/down. Also, calling it down when only one of the links went down is not desirable. Add changes to call the netif_carrier_up() function only when first link is brought up. Similarly, add changes to call the netif_carrier_down() function only when last link is brought down. In order to check the number of beaconing links in the given interface, introduce a new helper function ieee80211_num_beaconing_links(). Signed-off-by: Aditya Kumar Singh Link: https://msgid.link/20240227042251.1511122-3-quic_adisi@quicinc.com Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) (limited to 'net/mac80211') diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index bc0c1300e404..734368fd3f97 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1241,6 +1241,30 @@ ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata, return 0; } +static u8 ieee80211_num_beaconing_links(struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_link_data *link; + u8 link_id, num = 0; + + if (sdata->vif.type != NL80211_IFTYPE_AP && + sdata->vif.type != NL80211_IFTYPE_P2P_GO) + return num; + + if (!sdata->vif.valid_links) + return num; + + for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) { + link = sdata_dereference(sdata->link[link_id], sdata); + if (!link) + continue; + + if (sdata_dereference(link->u.ap.beacon, sdata)) + num++; + } + + return num; +} + static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ap_settings *params) { @@ -1470,7 +1494,9 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, ieee80211_vif_cfg_change_notify(sdata, BSS_CHANGED_SSID); ieee80211_link_info_change_notify(sdata, link, changed); - netif_carrier_on(dev); + if (ieee80211_num_beaconing_links(sdata) <= 1) + netif_carrier_on(dev); + list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) netif_carrier_on(vlan->dev); @@ -1592,7 +1618,9 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev, /* turn off carrier for this interface and dependent VLANs */ list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) netif_carrier_off(vlan->dev); - netif_carrier_off(dev); + + if (ieee80211_num_beaconing_links(sdata) <= 1) + netif_carrier_off(dev); /* remove beacon and probe response */ sdata->u.ap.active = false; -- cgit v1.2.3