mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	wifi: mac80211: flush only stations using requests links
Whenever sta_flush() function is invoked, all STAs present in that interface are flushed. In case of MLO, it is desirable to only flush such STAs that are at least using a given link id as one of their links. Add support for this by making change in the __sta_info_flush API argument to accept a link ID. And then, only if the STA is using the given link as one of its links, it would be flushed. Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com> Link: https://msgid.link/20240205162952.1697646-3-quic_adisi@quicinc.com [reword commit message, in particular this isn't about "active" links] Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
		
							parent
							
								
									f6ca96aa51
								
							
						
					
					
						commit
						ec67d6e0d4
					
				
					 8 changed files with 33 additions and 18 deletions
				
			
		| 
						 | 
				
			
			@ -1616,7 +1616,7 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev,
 | 
			
		|||
	link_conf->ema_ap = false;
 | 
			
		||||
	link_conf->bssid_indicator = 0;
 | 
			
		||||
 | 
			
		||||
	__sta_info_flush(sdata, true);
 | 
			
		||||
	__sta_info_flush(sdata, true, -1);
 | 
			
		||||
	ieee80211_free_keys(sdata, true);
 | 
			
		||||
 | 
			
		||||
	link_conf->enable_beacon = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -2096,7 +2096,7 @@ static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
 | 
			
		|||
	if (params->mac)
 | 
			
		||||
		return sta_info_destroy_addr_bss(sdata, params->mac);
 | 
			
		||||
 | 
			
		||||
	sta_info_flush(sdata);
 | 
			
		||||
	sta_info_flush(sdata, params->link_id);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -237,7 +237,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
 | 
			
		|||
	drv_reset_tsf(local, sdata);
 | 
			
		||||
 | 
			
		||||
	if (!ether_addr_equal(ifibss->bssid, bssid))
 | 
			
		||||
		sta_info_flush(sdata);
 | 
			
		||||
		sta_info_flush(sdata, -1);
 | 
			
		||||
 | 
			
		||||
	/* if merging, indicate to driver that we leave the old IBSS */
 | 
			
		||||
	if (sdata->vif.cfg.ibss_joined) {
 | 
			
		||||
| 
						 | 
				
			
			@ -682,7 +682,7 @@ static void ieee80211_ibss_disconnect(struct ieee80211_sub_if_data *sdata)
 | 
			
		|||
 | 
			
		||||
	ifibss->state = IEEE80211_IBSS_MLME_SEARCH;
 | 
			
		||||
 | 
			
		||||
	sta_info_flush(sdata);
 | 
			
		||||
	sta_info_flush(sdata, -1);
 | 
			
		||||
 | 
			
		||||
	spin_lock_bh(&ifibss->incomplete_lock);
 | 
			
		||||
	while (!list_empty(&ifibss->incomplete_stations)) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -511,7 +511,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
 | 
			
		|||
	 * would have removed them, but in other modes there shouldn't
 | 
			
		||||
	 * be any stations.
 | 
			
		||||
	 */
 | 
			
		||||
	flushed = sta_info_flush(sdata);
 | 
			
		||||
	flushed = sta_info_flush(sdata, -1);
 | 
			
		||||
	WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_AP_VLAN && flushed > 0);
 | 
			
		||||
 | 
			
		||||
	/* don't count this interface for allmulti while it is down */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1214,7 +1214,7 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
 | 
			
		|||
	netif_carrier_off(sdata->dev);
 | 
			
		||||
 | 
			
		||||
	/* flush STAs and mpaths on this iface */
 | 
			
		||||
	sta_info_flush(sdata);
 | 
			
		||||
	sta_info_flush(sdata, -1);
 | 
			
		||||
	ieee80211_free_keys(sdata, true);
 | 
			
		||||
	mesh_path_flush_by_iface(sdata);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3151,7 +3151,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
 | 
			
		|||
	sdata->vif.cfg.ssid_len = 0;
 | 
			
		||||
 | 
			
		||||
	/* remove AP and TDLS peers */
 | 
			
		||||
	sta_info_flush(sdata);
 | 
			
		||||
	sta_info_flush(sdata, -1);
 | 
			
		||||
 | 
			
		||||
	/* finally reset all BSS / config parameters */
 | 
			
		||||
	if (!ieee80211_vif_is_mld(&sdata->vif))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -208,7 +208,7 @@ int ieee80211_ocb_leave(struct ieee80211_sub_if_data *sdata)
 | 
			
		|||
	lockdep_assert_wiphy(sdata->local->hw.wiphy);
 | 
			
		||||
 | 
			
		||||
	ifocb->joined = false;
 | 
			
		||||
	sta_info_flush(sdata);
 | 
			
		||||
	sta_info_flush(sdata, -1);
 | 
			
		||||
 | 
			
		||||
	spin_lock_bh(&ifocb->incomplete_lock);
 | 
			
		||||
	while (!list_empty(&ifocb->incomplete_stations)) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1566,7 +1566,8 @@ void sta_info_stop(struct ieee80211_local *local)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int __sta_info_flush(struct ieee80211_sub_if_data *sdata, bool vlans)
 | 
			
		||||
int __sta_info_flush(struct ieee80211_sub_if_data *sdata, bool vlans,
 | 
			
		||||
		     int link_id)
 | 
			
		||||
{
 | 
			
		||||
	struct ieee80211_local *local = sdata->local;
 | 
			
		||||
	struct sta_info *sta, *tmp;
 | 
			
		||||
| 
						 | 
				
			
			@ -1580,12 +1581,18 @@ int __sta_info_flush(struct ieee80211_sub_if_data *sdata, bool vlans)
 | 
			
		|||
	WARN_ON(vlans && !sdata->bss);
 | 
			
		||||
 | 
			
		||||
	list_for_each_entry_safe(sta, tmp, &local->sta_list, list) {
 | 
			
		||||
		if (sdata == sta->sdata ||
 | 
			
		||||
		    (vlans && sdata->bss == sta->sdata->bss)) {
 | 
			
		||||
			if (!WARN_ON(__sta_info_destroy_part1(sta)))
 | 
			
		||||
				list_add(&sta->free_list, &free_list);
 | 
			
		||||
			ret++;
 | 
			
		||||
		}
 | 
			
		||||
		if (sdata != sta->sdata &&
 | 
			
		||||
		    (!vlans || sdata->bss != sta->sdata->bss))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if (link_id >= 0 && sta->sta.valid_links &&
 | 
			
		||||
		    !(sta->sta.valid_links & BIT(link_id)))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if (!WARN_ON(__sta_info_destroy_part1(sta)))
 | 
			
		||||
			list_add(&sta->free_list, &free_list);
 | 
			
		||||
 | 
			
		||||
		ret++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!list_empty(&free_list)) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -886,8 +886,12 @@ void sta_info_stop(struct ieee80211_local *local);
 | 
			
		|||
 *
 | 
			
		||||
 * @sdata: sdata to remove all stations from
 | 
			
		||||
 * @vlans: if the given interface is an AP interface, also flush VLANs
 | 
			
		||||
 * @link_id: if given (>=0), all those STA entries using @link_id only
 | 
			
		||||
 *	     will be removed. If -1 is passed, all STA entries will be
 | 
			
		||||
 *	     removed.
 | 
			
		||||
 */
 | 
			
		||||
int __sta_info_flush(struct ieee80211_sub_if_data *sdata, bool vlans);
 | 
			
		||||
int __sta_info_flush(struct ieee80211_sub_if_data *sdata, bool vlans,
 | 
			
		||||
		     int link_id);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * sta_info_flush - flush matching STA entries from the STA table
 | 
			
		||||
| 
						 | 
				
			
			@ -895,10 +899,14 @@ int __sta_info_flush(struct ieee80211_sub_if_data *sdata, bool vlans);
 | 
			
		|||
 * Returns the number of removed STA entries.
 | 
			
		||||
 *
 | 
			
		||||
 * @sdata: sdata to remove all stations from
 | 
			
		||||
 * @link_id: if given (>=0), all those STA entries using @link_id only
 | 
			
		||||
 *	     will be removed. If -1 is passed, all STA entries will be
 | 
			
		||||
 *	     removed.
 | 
			
		||||
 */
 | 
			
		||||
static inline int sta_info_flush(struct ieee80211_sub_if_data *sdata)
 | 
			
		||||
static inline int sta_info_flush(struct ieee80211_sub_if_data *sdata,
 | 
			
		||||
				 int link_id)
 | 
			
		||||
{
 | 
			
		||||
	return __sta_info_flush(sdata, false);
 | 
			
		||||
	return __sta_info_flush(sdata, false, link_id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void sta_set_rate_info_tx(struct sta_info *sta,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue