Commit acb8bca3 authored by Johannes Berg's avatar Johannes Berg
Browse files

wifi: mac80211: HW restart for MLO



Implement proper reconfiguration for interfaces that are
doing MLO, in order to be able to recover from HW restart
correctly.

Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarGregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230504134511.828474-6-gregory.greenman@intel.com


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 372a7148
Loading
Loading
Loading
Loading
+73 −34
Original line number Diff line number Diff line
@@ -2624,20 +2624,54 @@ int ieee80211_reconfig(struct ieee80211_local *local)

	/* Finally also reconfigure all the BSS information */
	list_for_each_entry(sdata, &local->interfaces, list) {
		/* common change flags for all interface types - link only */
		u32 changed = BSS_CHANGED_ERP_CTS_PROT |
			      BSS_CHANGED_ERP_PREAMBLE |
			      BSS_CHANGED_ERP_SLOT |
			      BSS_CHANGED_HT |
			      BSS_CHANGED_BASIC_RATES |
			      BSS_CHANGED_BEACON_INT |
			      BSS_CHANGED_BSSID |
			      BSS_CHANGED_CQM |
			      BSS_CHANGED_QOS |
			      BSS_CHANGED_TXPOWER |
			      BSS_CHANGED_MCAST_RATE;
		struct ieee80211_link_data *link = NULL;
		unsigned int link_id;
		u32 changed;
		u32 active_links = 0;

		if (!ieee80211_sdata_running(sdata))
			continue;

		sdata_lock(sdata);
		if (sdata->vif.valid_links) {
			struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS] = {
				[0] = &sdata->vif.bss_conf,
			};

			if (sdata->vif.type == NL80211_IFTYPE_STATION) {
				/* start with a single active link */
				active_links = sdata->vif.active_links;
				link_id = ffs(active_links) - 1;
				sdata->vif.active_links = BIT(link_id);
			}

			drv_change_vif_links(local, sdata, 0,
					     sdata->vif.active_links,
					     old);
		}

		for (link_id = 0;
		     link_id < ARRAY_SIZE(sdata->vif.link_conf);
		     link_id++) {
			struct ieee80211_link_data *link;
			if (sdata->vif.valid_links &&
			    !(sdata->vif.active_links & BIT(link_id)))
				continue;

			link = sdata_dereference(sdata->link[link_id], sdata);
			if (link)
			if (!link)
				continue;

			ieee80211_assign_chanctx(local, sdata, link);
		}

@@ -2658,27 +2692,16 @@ int ieee80211_reconfig(struct ieee80211_local *local)
					    &sdata->deflink.tx_conf[i]);
			break;
		}
		sdata_unlock(sdata);

		/* common change flags for all interface types */
		changed = BSS_CHANGED_ERP_CTS_PROT |
			  BSS_CHANGED_ERP_PREAMBLE |
			  BSS_CHANGED_ERP_SLOT |
			  BSS_CHANGED_HT |
			  BSS_CHANGED_BASIC_RATES |
			  BSS_CHANGED_BEACON_INT |
			  BSS_CHANGED_BSSID |
			  BSS_CHANGED_CQM |
			  BSS_CHANGED_QOS |
			  BSS_CHANGED_IDLE |
			  BSS_CHANGED_TXPOWER |
			  BSS_CHANGED_MCAST_RATE;

		if (sdata->vif.bss_conf.mu_mimo_owner)
			changed |= BSS_CHANGED_MU_GROUPS;

		if (!sdata->vif.valid_links)
			changed |= BSS_CHANGED_IDLE;

		switch (sdata->vif.type) {
		case NL80211_IFTYPE_STATION:
			if (!sdata->vif.valid_links) {
				changed |= BSS_CHANGED_ASSOC |
					   BSS_CHANGED_ARP_FILTER |
					   BSS_CHANGED_PS;
@@ -2691,9 +2714,20 @@ int ieee80211_reconfig(struct ieee80211_local *local)
				    sdata->vif.bss_conf.protected_keep_alive)
					changed |= BSS_CHANGED_KEEP_ALIVE;

			sdata_lock(sdata);
			ieee80211_bss_info_change_notify(sdata, changed);
			sdata_unlock(sdata);
				if (sdata->vif.bss_conf.eht_puncturing)
					changed |= BSS_CHANGED_EHT_PUNCTURING;

				ieee80211_bss_info_change_notify(sdata,
								 changed);
			} else if (!WARN_ON(!link)) {
				ieee80211_link_info_change_notify(sdata, link,
								  changed);
				changed = BSS_CHANGED_ASSOC |
					  BSS_CHANGED_IDLE |
					  BSS_CHANGED_PS |
					  BSS_CHANGED_ARP_FILTER;
				ieee80211_vif_cfg_change_notify(sdata, changed);
			}
			break;
		case NL80211_IFTYPE_OCB:
			changed |= BSS_CHANGED_OCB;
@@ -2728,6 +2762,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
		case NL80211_IFTYPE_NAN:
			res = ieee80211_reconfig_nan(sdata);
			if (res < 0) {
				sdata_unlock(sdata);
				ieee80211_handle_reconfig_failure(local);
				return res;
			}
@@ -2745,6 +2780,10 @@ int ieee80211_reconfig(struct ieee80211_local *local)
			WARN_ON(1);
			break;
		}
		sdata_unlock(sdata);

		if (active_links)
			ieee80211_set_active_links(&sdata->vif, active_links);
	}

	ieee80211_recalc_ps(local);