Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.14.15.
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * MLO link handling
  4 *
  5 * Copyright (C) 2022-2024 Intel Corporation
  6 */
  7#include <linux/slab.h>
  8#include <linux/kernel.h>
  9#include <net/mac80211.h>
 10#include "ieee80211_i.h"
 11#include "driver-ops.h"
 12#include "key.h"
 13#include "debugfs_netdev.h"
 14
 15void ieee80211_link_setup(struct ieee80211_link_data *link)
 16{
 17	if (link->sdata->vif.type == NL80211_IFTYPE_STATION)
 18		ieee80211_mgd_setup_link(link);
 19}
 20
 21void ieee80211_link_init(struct ieee80211_sub_if_data *sdata,
 22			 int link_id,
 23			 struct ieee80211_link_data *link,
 24			 struct ieee80211_bss_conf *link_conf)
 25{
 26	bool deflink = link_id < 0;
 27
 28	if (link_id < 0)
 29		link_id = 0;
 30
 31	rcu_assign_pointer(sdata->vif.link_conf[link_id], link_conf);
 32	rcu_assign_pointer(sdata->link[link_id], link);
 33
 34	link->sdata = sdata;
 35	link->link_id = link_id;
 36	link->conf = link_conf;
 37	link_conf->link_id = link_id;
 38	link_conf->vif = &sdata->vif;
 39	link->ap_power_level = IEEE80211_UNSET_POWER_LEVEL;
 40	link->user_power_level = sdata->local->user_power_level;
 41	link_conf->txpower = INT_MIN;
 42
 43	wiphy_work_init(&link->csa.finalize_work,
 44			ieee80211_csa_finalize_work);
 45	wiphy_work_init(&link->color_change_finalize_work,
 46			ieee80211_color_change_finalize_work);
 47	wiphy_delayed_work_init(&link->color_collision_detect_work,
 48				ieee80211_color_collision_detection_work);
 49	INIT_LIST_HEAD(&link->assigned_chanctx_list);
 50	INIT_LIST_HEAD(&link->reserved_chanctx_list);
 51	wiphy_delayed_work_init(&link->dfs_cac_timer_work,
 52				ieee80211_dfs_cac_timer_work);
 53
 54	if (!deflink) {
 55		switch (sdata->vif.type) {
 56		case NL80211_IFTYPE_AP:
 57			ether_addr_copy(link_conf->addr,
 58					sdata->wdev.links[link_id].addr);
 59			link_conf->bssid = link_conf->addr;
 60			WARN_ON(!(sdata->wdev.valid_links & BIT(link_id)));
 61			break;
 62		case NL80211_IFTYPE_STATION:
 63			/* station sets the bssid in ieee80211_mgd_setup_link */
 64			break;
 65		default:
 66			WARN_ON(1);
 67		}
 68
 69		ieee80211_link_debugfs_add(link);
 70	}
 71}
 72
 73void ieee80211_link_stop(struct ieee80211_link_data *link)
 74{
 75	if (link->sdata->vif.type == NL80211_IFTYPE_STATION)
 76		ieee80211_mgd_stop_link(link);
 77
 78	wiphy_delayed_work_cancel(link->sdata->local->hw.wiphy,
 79				  &link->color_collision_detect_work);
 80	wiphy_work_cancel(link->sdata->local->hw.wiphy,
 81			  &link->color_change_finalize_work);
 82	wiphy_work_cancel(link->sdata->local->hw.wiphy,
 83			  &link->csa.finalize_work);
 84
 85	if (link->sdata->wdev.links[link->link_id].cac_started) {
 86		wiphy_delayed_work_cancel(link->sdata->local->hw.wiphy,
 87					  &link->dfs_cac_timer_work);
 88		cfg80211_cac_event(link->sdata->dev,
 89				   &link->conf->chanreq.oper,
 90				   NL80211_RADAR_CAC_ABORTED,
 91				   GFP_KERNEL, link->link_id);
 92	}
 93
 94	ieee80211_link_release_channel(link);
 95}
 96
 97struct link_container {
 98	struct ieee80211_link_data data;
 99	struct ieee80211_bss_conf conf;
100};
101
102static void ieee80211_tear_down_links(struct ieee80211_sub_if_data *sdata,
103				      struct link_container **links, u16 mask)
104{
105	struct ieee80211_link_data *link;
106	LIST_HEAD(keys);
107	unsigned int link_id;
108
109	for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) {
110		if (!(mask & BIT(link_id)))
111			continue;
112		link = &links[link_id]->data;
113		if (link_id == 0 && !link)
114			link = &sdata->deflink;
115		if (WARN_ON(!link))
116			continue;
117		ieee80211_remove_link_keys(link, &keys);
118		ieee80211_link_debugfs_remove(link);
119		ieee80211_link_stop(link);
120	}
121
122	synchronize_rcu();
123
124	ieee80211_free_key_list(sdata->local, &keys);
125}
126
127static void ieee80211_free_links(struct ieee80211_sub_if_data *sdata,
128				 struct link_container **links)
129{
130	unsigned int link_id;
131
132	for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++)
133		kfree(links[link_id]);
134}
135
136static int ieee80211_check_dup_link_addrs(struct ieee80211_sub_if_data *sdata)
137{
138	unsigned int i, j;
139
140	for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) {
141		struct ieee80211_link_data *link1;
142
143		link1 = sdata_dereference(sdata->link[i], sdata);
144		if (!link1)
145			continue;
146		for (j = i + 1; j < IEEE80211_MLD_MAX_NUM_LINKS; j++) {
147			struct ieee80211_link_data *link2;
148
149			link2 = sdata_dereference(sdata->link[j], sdata);
150			if (!link2)
151				continue;
152
153			if (ether_addr_equal(link1->conf->addr,
154					     link2->conf->addr))
155				return -EALREADY;
156		}
157	}
158
159	return 0;
160}
161
162static void ieee80211_set_vif_links_bitmaps(struct ieee80211_sub_if_data *sdata,
163					    u16 valid_links, u16 dormant_links)
164{
165	sdata->vif.valid_links = valid_links;
166	sdata->vif.dormant_links = dormant_links;
167
168	if (!valid_links ||
169	    WARN((~valid_links & dormant_links) ||
170		 !(valid_links & ~dormant_links),
171		 "Invalid links: valid=0x%x, dormant=0x%x",
172		 valid_links, dormant_links)) {
173		sdata->vif.active_links = 0;
174		sdata->vif.dormant_links = 0;
175		return;
176	}
177
178	switch (sdata->vif.type) {
179	case NL80211_IFTYPE_AP:
180		/* in an AP all links are always active */
181		sdata->vif.active_links = valid_links;
182
183		/* AP links are not expected to be disabled */
184		WARN_ON(dormant_links);
185		break;
186	case NL80211_IFTYPE_STATION:
187		if (sdata->vif.active_links)
188			break;
189		sdata->vif.active_links = valid_links & ~dormant_links;
190		WARN_ON(hweight16(sdata->vif.active_links) > 1);
191		break;
192	default:
193		WARN_ON(1);
194	}
195}
196
197static int ieee80211_vif_update_links(struct ieee80211_sub_if_data *sdata,
198				      struct link_container **to_free,
199				      u16 new_links, u16 dormant_links)
200{
201	u16 old_links = sdata->vif.valid_links;
202	u16 old_active = sdata->vif.active_links;
203	unsigned long add = new_links & ~old_links;
204	unsigned long rem = old_links & ~new_links;
205	unsigned int link_id;
206	int ret;
207	struct link_container *links[IEEE80211_MLD_MAX_NUM_LINKS] = {}, *link;
208	struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS];
209	struct ieee80211_link_data *old_data[IEEE80211_MLD_MAX_NUM_LINKS];
210	bool use_deflink = old_links == 0; /* set for error case */
211
212	lockdep_assert_wiphy(sdata->local->hw.wiphy);
213
214	memset(to_free, 0, sizeof(links));
215
216	if (old_links == new_links && dormant_links == sdata->vif.dormant_links)
217		return 0;
218
219	/* if there were no old links, need to clear the pointers to deflink */
220	if (!old_links)
221		rem |= BIT(0);
222
223	/* allocate new link structures first */
224	for_each_set_bit(link_id, &add, IEEE80211_MLD_MAX_NUM_LINKS) {
225		link = kzalloc(sizeof(*link), GFP_KERNEL);
226		if (!link) {
227			ret = -ENOMEM;
228			goto free;
229		}
230		links[link_id] = link;
231	}
232
233	/* keep track of the old pointers for the driver */
234	BUILD_BUG_ON(sizeof(old) != sizeof(sdata->vif.link_conf));
235	memcpy(old, sdata->vif.link_conf, sizeof(old));
236	/* and for us in error cases */
237	BUILD_BUG_ON(sizeof(old_data) != sizeof(sdata->link));
238	memcpy(old_data, sdata->link, sizeof(old_data));
239
240	/* grab old links to free later */
241	for_each_set_bit(link_id, &rem, IEEE80211_MLD_MAX_NUM_LINKS) {
242		if (rcu_access_pointer(sdata->link[link_id]) != &sdata->deflink) {
243			/*
244			 * we must have allocated the data through this path so
245			 * we know we can free both at the same time
246			 */
247			to_free[link_id] = container_of(rcu_access_pointer(sdata->link[link_id]),
248							typeof(*links[link_id]),
249							data);
250		}
251
252		RCU_INIT_POINTER(sdata->link[link_id], NULL);
253		RCU_INIT_POINTER(sdata->vif.link_conf[link_id], NULL);
254	}
255
256	if (!old_links)
257		ieee80211_debugfs_recreate_netdev(sdata, true);
258
259	/* link them into data structures */
260	for_each_set_bit(link_id, &add, IEEE80211_MLD_MAX_NUM_LINKS) {
261		WARN_ON(!use_deflink &&
262			rcu_access_pointer(sdata->link[link_id]) == &sdata->deflink);
263
264		link = links[link_id];
265		ieee80211_link_init(sdata, link_id, &link->data, &link->conf);
266		ieee80211_link_setup(&link->data);
267	}
268
269	if (new_links == 0)
270		ieee80211_link_init(sdata, -1, &sdata->deflink,
271				    &sdata->vif.bss_conf);
272
273	ret = ieee80211_check_dup_link_addrs(sdata);
274	if (!ret) {
275		/* for keys we will not be able to undo this */
276		ieee80211_tear_down_links(sdata, to_free, rem);
277
278		ieee80211_set_vif_links_bitmaps(sdata, new_links, dormant_links);
279
280		/* tell the driver */
281		ret = drv_change_vif_links(sdata->local, sdata,
282					   old_links & old_active,
283					   new_links & sdata->vif.active_links,
284					   old);
285		if (!new_links)
286			ieee80211_debugfs_recreate_netdev(sdata, false);
287	}
288
289	if (ret) {
290		/* restore config */
291		memcpy(sdata->link, old_data, sizeof(old_data));
292		memcpy(sdata->vif.link_conf, old, sizeof(old));
293		ieee80211_set_vif_links_bitmaps(sdata, old_links, dormant_links);
294		/* and free (only) the newly allocated links */
295		memset(to_free, 0, sizeof(links));
296		goto free;
297	}
298
299	/* use deflink/bss_conf again if and only if there are no more links */
300	use_deflink = new_links == 0;
301
302	goto deinit;
303free:
304	/* if we failed during allocation, only free all */
305	for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) {
306		kfree(links[link_id]);
307		links[link_id] = NULL;
308	}
309deinit:
310	if (use_deflink)
311		ieee80211_link_init(sdata, -1, &sdata->deflink,
312				    &sdata->vif.bss_conf);
313	return ret;
314}
315
316int ieee80211_vif_set_links(struct ieee80211_sub_if_data *sdata,
317			    u16 new_links, u16 dormant_links)
318{
319	struct link_container *links[IEEE80211_MLD_MAX_NUM_LINKS];
320	int ret;
321
322	ret = ieee80211_vif_update_links(sdata, links, new_links,
323					 dormant_links);
324	ieee80211_free_links(sdata, links);
325
326	return ret;
327}
328
329static int _ieee80211_set_active_links(struct ieee80211_sub_if_data *sdata,
330				       u16 active_links)
331{
332	struct ieee80211_bss_conf *link_confs[IEEE80211_MLD_MAX_NUM_LINKS];
333	struct ieee80211_local *local = sdata->local;
334	u16 old_active = sdata->vif.active_links;
335	unsigned long rem = old_active & ~active_links;
336	unsigned long add = active_links & ~old_active;
337	struct sta_info *sta;
338	unsigned int link_id;
339	int ret, i;
340
341	if (!ieee80211_sdata_running(sdata))
342		return -ENETDOWN;
343
344	if (sdata->vif.type != NL80211_IFTYPE_STATION)
345		return -EINVAL;
346
347	if (active_links & ~ieee80211_vif_usable_links(&sdata->vif))
348		return -EINVAL;
349
350	/* nothing to do */
351	if (old_active == active_links)
352		return 0;
353
354	for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++)
355		link_confs[i] = sdata_dereference(sdata->vif.link_conf[i],
356						  sdata);
357
358	if (add) {
359		sdata->vif.active_links |= active_links;
360		ret = drv_change_vif_links(local, sdata,
361					   old_active,
362					   sdata->vif.active_links,
363					   link_confs);
364		if (ret) {
365			sdata->vif.active_links = old_active;
366			return ret;
367		}
368	}
369
370	for_each_set_bit(link_id, &rem, IEEE80211_MLD_MAX_NUM_LINKS) {
371		struct ieee80211_link_data *link;
372
373		link = sdata_dereference(sdata->link[link_id], sdata);
374
375		ieee80211_teardown_tdls_peers(link);
376
377		__ieee80211_link_release_channel(link, true);
378
379		/*
380		 * If CSA is (still) active while the link is deactivated,
381		 * just schedule the channel switch work for the time we
382		 * had previously calculated, and we'll take the process
383		 * from there.
384		 */
385		if (link->conf->csa_active)
386			wiphy_delayed_work_queue(local->hw.wiphy,
387						 &link->u.mgd.csa.switch_work,
388						 link->u.mgd.csa.time -
389						 jiffies);
390	}
391
392	for_each_set_bit(link_id, &add, IEEE80211_MLD_MAX_NUM_LINKS) {
393		struct ieee80211_link_data *link;
394
395		link = sdata_dereference(sdata->link[link_id], sdata);
396
397		/*
398		 * This call really should not fail. Unfortunately, it appears
399		 * that this may happen occasionally with some drivers. Should
400		 * it happen, we are stuck in a bad place as going backwards is
401		 * not really feasible.
402		 *
403		 * So lets just tell link_use_channel that it must not fail to
404		 * assign the channel context (from mac80211's perspective) and
405		 * assume the driver is going to trigger a recovery flow if it
406		 * had a failure.
407		 * That really is not great nor guaranteed to work. But at least
408		 * the internal mac80211 state remains consistent and there is
409		 * a chance that we can recover.
410		 */
411		ret = _ieee80211_link_use_channel(link,
412						  &link->conf->chanreq,
413						  IEEE80211_CHANCTX_SHARED,
414						  true);
415		WARN_ON_ONCE(ret);
416
417		/*
418		 * inform about the link info changed parameters after all
419		 * stations are also added
420		 */
421	}
422
423	list_for_each_entry(sta, &local->sta_list, list) {
424		if (sdata != sta->sdata)
425			continue;
426
427		/* this is very temporary, but do it anyway */
428		__ieee80211_sta_recalc_aggregates(sta,
429						  old_active | active_links);
430
431		ret = drv_change_sta_links(local, sdata, &sta->sta,
432					   old_active,
433					   old_active | active_links);
434		WARN_ON_ONCE(ret);
435	}
436
437	ret = ieee80211_key_switch_links(sdata, rem, add);
438	WARN_ON_ONCE(ret);
439
440	list_for_each_entry(sta, &local->sta_list, list) {
441		if (sdata != sta->sdata)
442			continue;
443
444		__ieee80211_sta_recalc_aggregates(sta, active_links);
445
446		ret = drv_change_sta_links(local, sdata, &sta->sta,
447					   old_active | active_links,
448					   active_links);
449		WARN_ON_ONCE(ret);
450
451		/*
452		 * Do it again, just in case - the driver might very
453		 * well have called ieee80211_sta_recalc_aggregates()
454		 * from there when filling in the new links, which
455		 * would set it wrong since the vif's active links are
456		 * not switched yet...
457		 */
458		__ieee80211_sta_recalc_aggregates(sta, active_links);
459	}
460
461	for_each_set_bit(link_id, &add, IEEE80211_MLD_MAX_NUM_LINKS) {
462		struct ieee80211_link_data *link;
463
464		link = sdata_dereference(sdata->link[link_id], sdata);
465
466		ieee80211_mgd_set_link_qos_params(link);
467		ieee80211_link_info_change_notify(sdata, link,
468						  BSS_CHANGED_ERP_CTS_PROT |
469						  BSS_CHANGED_ERP_PREAMBLE |
470						  BSS_CHANGED_ERP_SLOT |
471						  BSS_CHANGED_HT |
472						  BSS_CHANGED_BASIC_RATES |
473						  BSS_CHANGED_BSSID |
474						  BSS_CHANGED_CQM |
475						  BSS_CHANGED_QOS |
476						  BSS_CHANGED_TXPOWER |
477						  BSS_CHANGED_BANDWIDTH |
478						  BSS_CHANGED_TWT |
479						  BSS_CHANGED_HE_OBSS_PD |
480						  BSS_CHANGED_HE_BSS_COLOR);
481	}
482
483	old_active = sdata->vif.active_links;
484	sdata->vif.active_links = active_links;
485
486	if (rem) {
487		ret = drv_change_vif_links(local, sdata, old_active,
488					   active_links, link_confs);
489		WARN_ON_ONCE(ret);
490	}
491
492	return 0;
493}
494
495int ieee80211_set_active_links(struct ieee80211_vif *vif, u16 active_links)
496{
497	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
498	struct ieee80211_local *local = sdata->local;
499	u16 old_active;
500	int ret;
501
502	lockdep_assert_wiphy(local->hw.wiphy);
503
504	if (WARN_ON(!active_links))
505		return -EINVAL;
506
507	old_active = sdata->vif.active_links;
508	if (old_active == active_links)
509		return 0;
510
511	if (!drv_can_activate_links(local, sdata, active_links))
512		return -EINVAL;
513
514	if (old_active & active_links) {
515		/*
516		 * if there's at least one link that stays active across
517		 * the change then switch to it (to those) first, and
518		 * then enable the additional links
519		 */
520		ret = _ieee80211_set_active_links(sdata,
521						  old_active & active_links);
522		if (!ret)
523			ret = _ieee80211_set_active_links(sdata, active_links);
524	} else {
525		/* otherwise switch directly */
526		ret = _ieee80211_set_active_links(sdata, active_links);
527	}
528
529	return ret;
530}
531EXPORT_SYMBOL_GPL(ieee80211_set_active_links);
532
533void ieee80211_set_active_links_async(struct ieee80211_vif *vif,
534				      u16 active_links)
535{
536	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
537
538	if (WARN_ON(!active_links))
539		return;
540
541	if (!ieee80211_sdata_running(sdata))
542		return;
543
544	if (sdata->vif.type != NL80211_IFTYPE_STATION)
545		return;
546
547	if (active_links & ~ieee80211_vif_usable_links(&sdata->vif))
548		return;
549
550	/* nothing to do */
551	if (sdata->vif.active_links == active_links)
552		return;
553
554	sdata->desired_active_links = active_links;
555	wiphy_work_queue(sdata->local->hw.wiphy, &sdata->activate_links_work);
556}
557EXPORT_SYMBOL_GPL(ieee80211_set_active_links_async);