File Index
Files and directories
Sign in
FILE

offchannel.c

File preview with syntax highlighting.

linux-6.19.14/net/mac80211/offchannel.c C
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Off-channel operation helpers
   4 *
   5 * Copyright 2003, Jouni Malinen <jkmaline@cc.hut.fi>
   6 * Copyright 2004, Instant802 Networks, Inc.
   7 * Copyright 2005, Devicescape Software, Inc.
   8 * Copyright 2006-2007	Jiri Benc <jbenc@suse.cz>
   9 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
  10 * Copyright 2009	Johannes Berg <johannes@sipsolutions.net>
  11 * Copyright (C) 2019, 2022-2025 Intel Corporation
  12 */
  13#include <linux/export.h>
  14#include <net/mac80211.h>
  15#include "ieee80211_i.h"
  16#include "driver-ops.h"
  17
  18/*
  19 * Tell our hardware to disable PS.
  20 * Optionally inform AP that we will go to sleep so that it will buffer
  21 * the frames while we are doing off-channel work.  This is optional
  22 * because we *may* be doing work on-operating channel, and want our
  23 * hardware unconditionally awake, but still let the AP send us normal frames.
  24 */
  25static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata)
  26{
  27	struct ieee80211_local *local = sdata->local;
  28	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
  29	bool offchannel_ps_enabled = false;
  30
  31	/* FIXME: what to do when local->pspolling is true? */
  32
  33	timer_delete_sync(&local->dynamic_ps_timer);
  34	timer_delete_sync(&ifmgd->bcn_mon_timer);
  35	timer_delete_sync(&ifmgd->conn_mon_timer);
  36
  37	wiphy_work_cancel(local->hw.wiphy, &local->dynamic_ps_enable_work);
  38
  39	if (local->hw.conf.flags & IEEE80211_CONF_PS) {
  40		offchannel_ps_enabled = true;
  41		local->hw.conf.flags &= ~IEEE80211_CONF_PS;
  42		ieee80211_hw_config(local, -1, IEEE80211_CONF_CHANGE_PS);
  43	}
  44
  45	if (!offchannel_ps_enabled ||
  46	    !ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK))
  47		/*
  48		 * If power save was enabled, no need to send a nullfunc
  49		 * frame because AP knows that we are sleeping. But if the
  50		 * hardware is creating the nullfunc frame for power save
  51		 * status (ie. IEEE80211_HW_PS_NULLFUNC_STACK is not
  52		 * enabled) and power save was enabled, the firmware just
  53		 * sent a null frame with power save disabled. So we need
  54		 * to send a new nullfunc frame to inform the AP that we
  55		 * are again sleeping.
  56		 */
  57		ieee80211_send_nullfunc(local, sdata, true);
  58}
  59
  60/* inform AP that we are awake again */
  61static void ieee80211_offchannel_ps_disable(struct ieee80211_sub_if_data *sdata)
  62{
  63	struct ieee80211_local *local = sdata->local;
  64
  65	if (!local->ps_sdata)
  66		ieee80211_send_nullfunc(local, sdata, false);
  67	else if (local->hw.conf.dynamic_ps_timeout > 0) {
  68		/*
  69		 * the dynamic_ps_timer had been running before leaving the
  70		 * operating channel, restart the timer now and send a nullfunc
  71		 * frame to inform the AP that we are awake so that AP sends
  72		 * the buffered packets (if any).
  73		 */
  74		ieee80211_send_nullfunc(local, sdata, false);
  75		mod_timer(&local->dynamic_ps_timer, jiffies +
  76			  msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
  77	}
  78
  79	ieee80211_sta_reset_beacon_monitor(sdata);
  80	ieee80211_sta_reset_conn_monitor(sdata);
  81}
  82
  83void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local)
  84{
  85	struct ieee80211_sub_if_data *sdata;
  86
  87	lockdep_assert_wiphy(local->hw.wiphy);
  88
  89	if (WARN_ON(!local->emulate_chanctx))
  90		return;
  91
  92	/*
  93	 * notify the AP about us leaving the channel and stop all
  94	 * STA interfaces.
  95	 */
  96
  97	/*
  98	 * Stop queues and transmit all frames queued by the driver
  99	 * before sending nullfunc to enable powersave at the AP.
 100	 */
 101	ieee80211_stop_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP,
 102					IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL,
 103					false);
 104	ieee80211_flush_queues(local, NULL, false);
 105
 106	list_for_each_entry(sdata, &local->interfaces, list) {
 107		if (!ieee80211_sdata_running(sdata))
 108			continue;
 109
 110		if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE ||
 111		    sdata->vif.type == NL80211_IFTYPE_NAN)
 112			continue;
 113
 114		if (sdata->vif.type != NL80211_IFTYPE_MONITOR)
 115			set_bit(SDATA_STATE_OFFCHANNEL, &sdata->state);
 116
 117		/* Check to see if we should disable beaconing. */
 118		if (sdata->vif.bss_conf.enable_beacon) {
 119			set_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED,
 120				&sdata->state);
 121			sdata->vif.bss_conf.enable_beacon = false;
 122			ieee80211_link_info_change_notify(
 123				sdata, &sdata->deflink,
 124				BSS_CHANGED_BEACON_ENABLED);
 125		}
 126
 127		if (sdata->vif.type == NL80211_IFTYPE_STATION &&
 128		    sdata->u.mgd.associated)
 129			ieee80211_offchannel_ps_enable(sdata);
 130	}
 131}
 132
 133void ieee80211_offchannel_return(struct ieee80211_local *local)
 134{
 135	struct ieee80211_sub_if_data *sdata;
 136
 137	lockdep_assert_wiphy(local->hw.wiphy);
 138
 139	if (WARN_ON(!local->emulate_chanctx))
 140		return;
 141
 142	list_for_each_entry(sdata, &local->interfaces, list) {
 143		if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE)
 144			continue;
 145
 146		if (sdata->vif.type != NL80211_IFTYPE_MONITOR)
 147			clear_bit(SDATA_STATE_OFFCHANNEL, &sdata->state);
 148
 149		if (!ieee80211_sdata_running(sdata))
 150			continue;
 151
 152		/* Tell AP we're back */
 153		if (sdata->vif.type == NL80211_IFTYPE_STATION &&
 154		    sdata->u.mgd.associated)
 155			ieee80211_offchannel_ps_disable(sdata);
 156
 157		if (test_and_clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED,
 158				       &sdata->state)) {
 159			sdata->vif.bss_conf.enable_beacon = true;
 160			ieee80211_link_info_change_notify(
 161				sdata, &sdata->deflink,
 162				BSS_CHANGED_BEACON_ENABLED);
 163		}
 164	}
 165
 166	ieee80211_wake_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP,
 167					IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL,
 168					false);
 169}
 170
 171static void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc)
 172{
 173	/* was never transmitted */
 174	if (roc->frame) {
 175		cfg80211_mgmt_tx_status(&roc->sdata->wdev, roc->mgmt_tx_cookie,
 176					roc->frame->data, roc->frame->len,
 177					false, GFP_KERNEL);
 178		ieee80211_free_txskb(&roc->sdata->local->hw, roc->frame);
 179	}
 180
 181	if (!roc->mgmt_tx_cookie)
 182		cfg80211_remain_on_channel_expired(&roc->sdata->wdev,
 183						   roc->cookie, roc->chan,
 184						   GFP_KERNEL);
 185	else
 186		cfg80211_tx_mgmt_expired(&roc->sdata->wdev,
 187					 roc->mgmt_tx_cookie,
 188					 roc->chan, GFP_KERNEL);
 189
 190	list_del(&roc->list);
 191	kfree(roc);
 192}
 193
 194static unsigned long ieee80211_end_finished_rocs(struct ieee80211_local *local,
 195						 unsigned long now)
 196{
 197	struct ieee80211_roc_work *roc, *tmp;
 198	long remaining_dur_min = LONG_MAX;
 199
 200	lockdep_assert_wiphy(local->hw.wiphy);
 201
 202	list_for_each_entry_safe(roc, tmp, &local->roc_list, list) {
 203		long remaining;
 204
 205		if (!roc->started)
 206			break;
 207
 208		remaining = roc->start_time +
 209			    msecs_to_jiffies(roc->duration) -
 210			    now;
 211
 212		/* In case of HW ROC, it is possible that the HW finished the
 213		 * ROC session before the actual requested time. In such a case
 214		 * end the ROC session (disregarding the remaining time).
 215		 */
 216		if (roc->abort || roc->hw_begun || remaining <= 0)
 217			ieee80211_roc_notify_destroy(roc);
 218		else
 219			remaining_dur_min = min(remaining_dur_min, remaining);
 220	}
 221
 222	return remaining_dur_min;
 223}
 224
 225static bool ieee80211_recalc_sw_work(struct ieee80211_local *local,
 226				     unsigned long now)
 227{
 228	long dur = ieee80211_end_finished_rocs(local, now);
 229
 230	if (dur == LONG_MAX)
 231		return false;
 232
 233	wiphy_delayed_work_queue(local->hw.wiphy, &local->roc_work, dur);
 234	return true;
 235}
 236
 237static void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc,
 238					 unsigned long start_time)
 239{
 240	if (WARN_ON(roc->notified))
 241		return;
 242
 243	roc->start_time = start_time;
 244	roc->started = true;
 245
 246	if (roc->mgmt_tx_cookie) {
 247		if (!WARN_ON(!roc->frame)) {
 248			ieee80211_tx_skb_tid_band(roc->sdata, roc->frame, 7,
 249						  roc->chan->band);
 250			roc->frame = NULL;
 251		}
 252	} else {
 253		cfg80211_ready_on_channel(&roc->sdata->wdev, roc->cookie,
 254					  roc->chan, roc->req_duration,
 255					  GFP_KERNEL);
 256	}
 257
 258	roc->notified = true;
 259}
 260
 261static void ieee80211_hw_roc_start(struct wiphy *wiphy, struct wiphy_work *work)
 262{
 263	struct ieee80211_local *local =
 264		container_of(work, struct ieee80211_local, hw_roc_start);
 265	struct ieee80211_roc_work *roc;
 266
 267	lockdep_assert_wiphy(local->hw.wiphy);
 268
 269	list_for_each_entry(roc, &local->roc_list, list) {
 270		if (!roc->started)
 271			break;
 272
 273		roc->hw_begun = true;
 274		ieee80211_handle_roc_started(roc, local->hw_roc_start_time);
 275	}
 276}
 277
 278void ieee80211_ready_on_channel(struct ieee80211_hw *hw)
 279{
 280	struct ieee80211_local *local = hw_to_local(hw);
 281
 282	local->hw_roc_start_time = jiffies;
 283
 284	trace_api_ready_on_channel(local);
 285
 286	wiphy_work_queue(hw->wiphy, &local->hw_roc_start);
 287}
 288EXPORT_SYMBOL_GPL(ieee80211_ready_on_channel);
 289
 290static void _ieee80211_start_next_roc(struct ieee80211_local *local)
 291{
 292	struct ieee80211_roc_work *roc, *tmp;
 293	enum ieee80211_roc_type type;
 294	u32 min_dur, max_dur;
 295
 296	lockdep_assert_wiphy(local->hw.wiphy);
 297
 298	if (WARN_ON(list_empty(&local->roc_list)))
 299		return;
 300
 301	roc = list_first_entry(&local->roc_list, struct ieee80211_roc_work,
 302			       list);
 303
 304	if (WARN_ON(roc->started))
 305		return;
 306
 307	min_dur = roc->duration;
 308	max_dur = roc->duration;
 309	type = roc->type;
 310
 311	list_for_each_entry(tmp, &local->roc_list, list) {
 312		if (tmp == roc)
 313			continue;
 314		if (tmp->sdata != roc->sdata || tmp->chan != roc->chan)
 315			break;
 316		max_dur = max(tmp->duration, max_dur);
 317		min_dur = min(tmp->duration, min_dur);
 318		type = max(tmp->type, type);
 319	}
 320
 321	if (local->ops->remain_on_channel) {
 322		int ret = drv_remain_on_channel(local, roc->sdata, roc->chan,
 323						max_dur, type);
 324
 325		if (ret) {
 326			wiphy_warn(local->hw.wiphy,
 327				   "failed to start next HW ROC (%d)\n", ret);
 328			/*
 329			 * queue the work struct again to avoid recursion
 330			 * when multiple failures occur
 331			 */
 332			list_for_each_entry(tmp, &local->roc_list, list) {
 333				if (tmp->sdata != roc->sdata ||
 334				    tmp->chan != roc->chan)
 335					break;
 336				tmp->started = true;
 337				tmp->abort = true;
 338			}
 339			wiphy_work_queue(local->hw.wiphy, &local->hw_roc_done);
 340			return;
 341		}
 342
 343		/* we'll notify about the start once the HW calls back */
 344		list_for_each_entry(tmp, &local->roc_list, list) {
 345			if (tmp->sdata != roc->sdata || tmp->chan != roc->chan)
 346				break;
 347			tmp->started = true;
 348		}
 349	} else {
 350		/* If actually operating on the desired channel (with at least
 351		 * 20 MHz channel width) don't stop all the operations but still
 352		 * treat it as though the ROC operation started properly, so
 353		 * other ROC operations won't interfere with this one.
 354		 *
 355		 * Note: scan can't run, tmp_channel is what we use, so this
 356		 * must be the currently active channel.
 357		 */
 358		roc->on_channel = roc->chan == local->hw.conf.chandef.chan &&
 359				  local->hw.conf.chandef.width != NL80211_CHAN_WIDTH_5 &&
 360				  local->hw.conf.chandef.width != NL80211_CHAN_WIDTH_10;
 361
 362		/* start this ROC */
 363		ieee80211_recalc_idle(local);
 364
 365		if (!roc->on_channel) {
 366			ieee80211_offchannel_stop_vifs(local);
 367
 368			local->tmp_channel = roc->chan;
 369			ieee80211_hw_conf_chan(local);
 370		}
 371
 372		wiphy_delayed_work_queue(local->hw.wiphy, &local->roc_work,
 373					 msecs_to_jiffies(min_dur));
 374
 375		/* tell userspace or send frame(s) */
 376		list_for_each_entry(tmp, &local->roc_list, list) {
 377			if (tmp->sdata != roc->sdata || tmp->chan != roc->chan)
 378				break;
 379
 380			tmp->on_channel = roc->on_channel;
 381			ieee80211_handle_roc_started(tmp, jiffies);
 382		}
 383	}
 384}
 385
 386void ieee80211_start_next_roc(struct ieee80211_local *local)
 387{
 388	struct ieee80211_roc_work *roc;
 389
 390	lockdep_assert_wiphy(local->hw.wiphy);
 391
 392	if (list_empty(&local->roc_list)) {
 393		ieee80211_run_deferred_scan(local);
 394		return;
 395	}
 396
 397	/* defer roc if driver is not started (i.e. during reconfig) */
 398	if (local->in_reconfig)
 399		return;
 400
 401	roc = list_first_entry(&local->roc_list, struct ieee80211_roc_work,
 402			       list);
 403
 404	if (WARN_ON_ONCE(roc->started))
 405		return;
 406
 407	if (local->ops->remain_on_channel) {
 408		_ieee80211_start_next_roc(local);
 409	} else {
 410		/* delay it a bit */
 411		wiphy_delayed_work_queue(local->hw.wiphy, &local->roc_work,
 412					 round_jiffies_relative(HZ / 2));
 413	}
 414}
 415
 416void ieee80211_reconfig_roc(struct ieee80211_local *local)
 417{
 418	struct ieee80211_roc_work *roc, *tmp;
 419
 420	/*
 421	 * In the software implementation can just continue with the
 422	 * interruption due to reconfig, roc_work is still queued if
 423	 * needed.
 424	 */
 425	if (!local->ops->remain_on_channel)
 426		return;
 427
 428	/* flush work so nothing from the driver is still pending */
 429	wiphy_work_flush(local->hw.wiphy, &local->hw_roc_start);
 430	wiphy_work_flush(local->hw.wiphy, &local->hw_roc_done);
 431
 432	list_for_each_entry_safe(roc, tmp, &local->roc_list, list) {
 433		if (!roc->started)
 434			break;
 435
 436		if (!roc->hw_begun) {
 437			/* it didn't start in HW yet, so we can restart it */
 438			roc->started = false;
 439			continue;
 440		}
 441
 442		/* otherwise destroy it and tell userspace */
 443		ieee80211_roc_notify_destroy(roc);
 444	}
 445
 446	ieee80211_start_next_roc(local);
 447}
 448
 449static void __ieee80211_roc_work(struct ieee80211_local *local)
 450{
 451	struct ieee80211_roc_work *roc;
 452	bool on_channel;
 453
 454	lockdep_assert_wiphy(local->hw.wiphy);
 455
 456	if (WARN_ON(local->ops->remain_on_channel))
 457		return;
 458
 459	roc = list_first_entry_or_null(&local->roc_list,
 460				       struct ieee80211_roc_work, list);
 461	if (!roc)
 462		return;
 463
 464	if (!roc->started) {
 465		WARN_ON(!local->emulate_chanctx);
 466		_ieee80211_start_next_roc(local);
 467	} else {
 468		on_channel = roc->on_channel;
 469		if (ieee80211_recalc_sw_work(local, jiffies))
 470			return;
 471
 472		/* careful - roc pointer became invalid during recalc */
 473
 474		if (!on_channel) {
 475			ieee80211_flush_queues(local, NULL, false);
 476
 477			local->tmp_channel = NULL;
 478			ieee80211_hw_conf_chan(local);
 479
 480			ieee80211_offchannel_return(local);
 481		}
 482
 483		ieee80211_recalc_idle(local);
 484		ieee80211_start_next_roc(local);
 485	}
 486}
 487
 488static void ieee80211_roc_work(struct wiphy *wiphy, struct wiphy_work *work)
 489{
 490	struct ieee80211_local *local =
 491		container_of(work, struct ieee80211_local, roc_work.work);
 492
 493	lockdep_assert_wiphy(local->hw.wiphy);
 494
 495	__ieee80211_roc_work(local);
 496}
 497
 498static void ieee80211_hw_roc_done(struct wiphy *wiphy, struct wiphy_work *work)
 499{
 500	struct ieee80211_local *local =
 501		container_of(work, struct ieee80211_local, hw_roc_done);
 502
 503	lockdep_assert_wiphy(local->hw.wiphy);
 504
 505	ieee80211_end_finished_rocs(local, jiffies);
 506
 507	/* if there's another roc, start it now */
 508	ieee80211_start_next_roc(local);
 509}
 510
 511void ieee80211_remain_on_channel_expired(struct ieee80211_hw *hw)
 512{
 513	struct ieee80211_local *local = hw_to_local(hw);
 514
 515	trace_api_remain_on_channel_expired(local);
 516
 517	wiphy_work_queue(hw->wiphy, &local->hw_roc_done);
 518}
 519EXPORT_SYMBOL_GPL(ieee80211_remain_on_channel_expired);
 520
 521static bool
 522ieee80211_coalesce_hw_started_roc(struct ieee80211_local *local,
 523				  struct ieee80211_roc_work *new_roc,
 524				  struct ieee80211_roc_work *cur_roc)
 525{
 526	unsigned long now = jiffies;
 527	unsigned long remaining;
 528
 529	if (WARN_ON(!cur_roc->started))
 530		return false;
 531
 532	/* if it was scheduled in the hardware, but not started yet,
 533	 * we can only combine if the older one had a longer duration
 534	 */
 535	if (!cur_roc->hw_begun && new_roc->duration > cur_roc->duration)
 536		return false;
 537
 538	remaining = cur_roc->start_time +
 539		    msecs_to_jiffies(cur_roc->duration) -
 540		    now;
 541
 542	/* if it doesn't fit entirely, schedule a new one */
 543	if (new_roc->duration > jiffies_to_msecs(remaining))
 544		return false;
 545
 546	/* add just after the current one so we combine their finish later */
 547	list_add(&new_roc->list, &cur_roc->list);
 548
 549	/* if the existing one has already begun then let this one also
 550	 * begin, otherwise they'll both be marked properly by the work
 551	 * struct that runs once the driver notifies us of the beginning
 552	 */
 553	if (cur_roc->hw_begun) {
 554		new_roc->hw_begun = true;
 555		ieee80211_handle_roc_started(new_roc, now);
 556	}
 557
 558	return true;
 559}
 560
 561static int ieee80211_start_roc_work(struct ieee80211_local *local,
 562				    struct ieee80211_sub_if_data *sdata,
 563				    struct ieee80211_channel *channel,
 564				    unsigned int duration, u64 *cookie,
 565				    struct sk_buff *txskb,
 566				    enum ieee80211_roc_type type)
 567{
 568	struct ieee80211_roc_work *roc, *tmp;
 569	bool queued = false, combine_started = true;
 570	struct cfg80211_scan_request *req;
 571	int ret;
 572
 573	lockdep_assert_wiphy(local->hw.wiphy);
 574
 575	if (channel->freq_offset)
 576		/* this may work, but is untested */
 577		return -EOPNOTSUPP;
 578
 579	if (!local->emulate_chanctx && !local->ops->remain_on_channel)
 580		return -EOPNOTSUPP;
 581
 582	roc = kzalloc(sizeof(*roc), GFP_KERNEL);
 583	if (!roc)
 584		return -ENOMEM;
 585
 586	/*
 587	 * If the duration is zero, then the driver
 588	 * wouldn't actually do anything. Set it to
 589	 * 10 for now.
 590	 *
 591	 * TODO: cancel the off-channel operation
 592	 *       when we get the SKB's TX status and
 593	 *       the wait time was zero before.
 594	 */
 595	if (!duration)
 596		duration = 10;
 597
 598	roc->chan = channel;
 599	roc->duration = duration;
 600	roc->req_duration = duration;
 601	roc->frame = txskb;
 602	roc->type = type;
 603	roc->sdata = sdata;
 604
 605	/*
 606	 * cookie is either the roc cookie (for normal roc)
 607	 * or the SKB (for mgmt TX)
 608	 */
 609	if (!txskb) {
 610		roc->cookie = ieee80211_mgmt_tx_cookie(local);
 611		*cookie = roc->cookie;
 612	} else {
 613		roc->mgmt_tx_cookie = *cookie;
 614	}
 615
 616	req = wiphy_dereference(local->hw.wiphy, local->scan_req);
 617
 618	/* if there's no need to queue, handle it immediately */
 619	if (list_empty(&local->roc_list) &&
 620	    !local->scanning && !ieee80211_is_radar_required(local, req)) {
 621		/* if not HW assist, just queue & schedule work */
 622		if (!local->ops->remain_on_channel) {
 623			list_add_tail(&roc->list, &local->roc_list);
 624			wiphy_delayed_work_queue(local->hw.wiphy,
 625						 &local->roc_work, 0);
 626		} else {
 627			/* otherwise actually kick it off here
 628			 * (for error handling)
 629			 */
 630			ret = drv_remain_on_channel(local, sdata, channel,
 631						    duration, type);
 632			if (ret) {
 633				kfree(roc);
 634				return ret;
 635			}
 636			roc->started = true;
 637			list_add_tail(&roc->list, &local->roc_list);
 638		}
 639
 640		return 0;
 641	}
 642
 643	/* otherwise handle queueing */
 644
 645	list_for_each_entry(tmp, &local->roc_list, list) {
 646		if (tmp->chan != channel || tmp->sdata != sdata)
 647			continue;
 648
 649		/*
 650		 * Extend this ROC if possible: If it hasn't started, add
 651		 * just after the new one to combine.
 652		 */
 653		if (!tmp->started) {
 654			list_add(&roc->list, &tmp->list);
 655			queued = true;
 656			break;
 657		}
 658
 659		if (!combine_started)
 660			continue;
 661
 662		if (!local->ops->remain_on_channel) {
 663			/* If there's no hardware remain-on-channel, and
 664			 * doing so won't push us over the maximum r-o-c
 665			 * we allow, then we can just add the new one to
 666			 * the list and mark it as having started now.
 667			 * If it would push over the limit, don't try to
 668			 * combine with other started ones (that haven't
 669			 * been running as long) but potentially sort it
 670			 * with others that had the same fate.
 671			 */
 672			unsigned long now = jiffies;
 673			u32 elapsed = jiffies_to_msecs(now - tmp->start_time);
 674			struct wiphy *wiphy = local->hw.wiphy;
 675			u32 max_roc = wiphy->max_remain_on_channel_duration;
 676
 677			if (elapsed + roc->duration > max_roc) {
 678				combine_started = false;
 679				continue;
 680			}
 681
 682			list_add(&roc->list, &tmp->list);
 683			queued = true;
 684			roc->on_channel = tmp->on_channel;
 685			ieee80211_handle_roc_started(roc, now);
 686			ieee80211_recalc_sw_work(local, now);
 687			break;
 688		}
 689
 690		queued = ieee80211_coalesce_hw_started_roc(local, roc, tmp);
 691		if (queued)
 692			break;
 693		/* if it wasn't queued, perhaps it can be combined with
 694		 * another that also couldn't get combined previously,
 695		 * but no need to check for already started ones, since
 696		 * that can't work.
 697		 */
 698		combine_started = false;
 699	}
 700
 701	if (!queued)
 702		list_add_tail(&roc->list, &local->roc_list);
 703
 704	return 0;
 705}
 706
 707int ieee80211_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev,
 708				struct ieee80211_channel *chan,
 709				unsigned int duration, u64 *cookie)
 710{
 711	struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
 712	struct ieee80211_local *local = sdata->local;
 713
 714	lockdep_assert_wiphy(local->hw.wiphy);
 715
 716	return ieee80211_start_roc_work(local, sdata, chan,
 717					duration, cookie, NULL,
 718					IEEE80211_ROC_TYPE_NORMAL);
 719}
 720
 721static int ieee80211_cancel_roc(struct ieee80211_local *local,
 722				u64 cookie, bool mgmt_tx)
 723{
 724	struct ieee80211_roc_work *roc, *tmp, *found = NULL;
 725	int ret;
 726
 727	lockdep_assert_wiphy(local->hw.wiphy);
 728
 729	if (!cookie)
 730		return -ENOENT;
 731
 732	wiphy_work_flush(local->hw.wiphy, &local->hw_roc_start);
 733
 734	list_for_each_entry_safe(roc, tmp, &local->roc_list, list) {
 735		if (!mgmt_tx && roc->cookie != cookie)
 736			continue;
 737		else if (mgmt_tx && roc->mgmt_tx_cookie != cookie)
 738			continue;
 739
 740		found = roc;
 741		break;
 742	}
 743
 744	if (!found) {
 745		return -ENOENT;
 746	}
 747
 748	if (!found->started) {
 749		ieee80211_roc_notify_destroy(found);
 750		goto out_unlock;
 751	}
 752
 753	if (local->ops->remain_on_channel) {
 754		ret = drv_cancel_remain_on_channel(local, roc->sdata);
 755		if (WARN_ON_ONCE(ret)) {
 756			return ret;
 757		}
 758
 759		/*
 760		 * We could be racing against the notification from the driver:
 761		 *  + driver is handling the notification on CPU0
 762		 *  + user space is cancelling the remain on channel and
 763		 *    schedules the hw_roc_done worker.
 764		 *
 765		 *  Now hw_roc_done might start to run after the next roc will
 766		 *  start and mac80211 will think that this second roc has
 767		 *  ended prematurely.
 768		 *  Cancel the work to make sure that all the pending workers
 769		 *  have completed execution.
 770		 *  Note that this assumes that by the time the driver returns
 771		 *  from drv_cancel_remain_on_channel, it has completed all
 772		 *  the processing of related notifications.
 773		 */
 774		wiphy_work_cancel(local->hw.wiphy, &local->hw_roc_done);
 775
 776		/* TODO:
 777		 * if multiple items were combined here then we really shouldn't
 778		 * cancel them all - we should wait for as much time as needed
 779		 * for the longest remaining one, and only then cancel ...
 780		 */
 781		list_for_each_entry_safe(roc, tmp, &local->roc_list, list) {
 782			if (!roc->started)
 783				break;
 784			if (roc == found)
 785				found = NULL;
 786			ieee80211_roc_notify_destroy(roc);
 787		}
 788
 789		/* that really must not happen - it was started */
 790		WARN_ON(found);
 791
 792		ieee80211_start_next_roc(local);
 793	} else {
 794		/* go through work struct to return to the operating channel */
 795		found->abort = true;
 796		wiphy_delayed_work_queue(local->hw.wiphy, &local->roc_work, 0);
 797	}
 798
 799 out_unlock:
 800
 801	return 0;
 802}
 803
 804int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy,
 805				       struct wireless_dev *wdev, u64 cookie)
 806{
 807	struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
 808	struct ieee80211_local *local = sdata->local;
 809
 810	return ieee80211_cancel_roc(local, cookie, false);
 811}
 812
 813int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
 814		      struct cfg80211_mgmt_tx_params *params, u64 *cookie)
 815{
 816	struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
 817	struct ieee80211_local *local = sdata->local;
 818	struct sk_buff *skb;
 819	struct sta_info *sta = NULL;
 820	const struct ieee80211_mgmt *mgmt = (void *)params->buf;
 821	bool need_offchan = false;
 822	bool mlo_sta = false;
 823	int link_id = -1;
 824	u32 flags;
 825	int ret;
 826	u8 *data;
 827
 828	lockdep_assert_wiphy(local->hw.wiphy);
 829
 830	if (params->dont_wait_for_ack)
 831		flags = IEEE80211_TX_CTL_NO_ACK;
 832	else
 833		flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX |
 834			IEEE80211_TX_CTL_REQ_TX_STATUS;
 835
 836	if (params->no_cck)
 837		flags |= IEEE80211_TX_CTL_NO_CCK_RATE;
 838
 839	switch (sdata->vif.type) {
 840	case NL80211_IFTYPE_ADHOC:
 841		if (!sdata->vif.cfg.ibss_joined)
 842			need_offchan = true;
 843#ifdef CONFIG_MAC80211_MESH
 844		fallthrough;
 845	case NL80211_IFTYPE_MESH_POINT:
 846		if (ieee80211_vif_is_mesh(&sdata->vif) &&
 847		    !sdata->u.mesh.mesh_id_len)
 848			need_offchan = true;
 849#endif
 850		fallthrough;
 851	case NL80211_IFTYPE_AP:
 852	case NL80211_IFTYPE_AP_VLAN:
 853	case NL80211_IFTYPE_P2P_GO:
 854		if (sdata->vif.type != NL80211_IFTYPE_ADHOC &&
 855		    !ieee80211_vif_is_mesh(&sdata->vif) &&
 856		    !sdata->bss->active)
 857			need_offchan = true;
 858
 859		rcu_read_lock();
 860		sta = sta_info_get_bss(sdata, mgmt->da);
 861		mlo_sta = sta && sta->sta.mlo;
 862
 863		if (!ieee80211_is_action(mgmt->frame_control) ||
 864		    mgmt->u.action.category == WLAN_CATEGORY_PUBLIC ||
 865		    mgmt->u.action.category == WLAN_CATEGORY_SELF_PROTECTED ||
 866		    mgmt->u.action.category == WLAN_CATEGORY_SPECTRUM_MGMT) {
 867			rcu_read_unlock();
 868			break;
 869		}
 870
 871		if (!sta) {
 872			rcu_read_unlock();
 873			return -ENOLINK;
 874		}
 875		if (params->link_id >= 0 &&
 876		    !(sta->sta.valid_links & BIT(params->link_id))) {
 877			rcu_read_unlock();
 878			return -ENOLINK;
 879		}
 880		link_id = params->link_id;
 881		rcu_read_unlock();
 882		break;
 883	case NL80211_IFTYPE_STATION:
 884	case NL80211_IFTYPE_P2P_CLIENT:
 885		if (!sdata->u.mgd.associated ||
 886		    (params->offchan && params->wait &&
 887		     local->ops->remain_on_channel &&
 888		     memcmp(sdata->vif.cfg.ap_addr, mgmt->bssid, ETH_ALEN))) {
 889			need_offchan = true;
 890		} else if (sdata->u.mgd.associated &&
 891			   ether_addr_equal(sdata->vif.cfg.ap_addr, mgmt->da)) {
 892			sta = sta_info_get_bss(sdata, mgmt->da);
 893			mlo_sta = sta && sta->sta.mlo;
 894		}
 895		break;
 896	case NL80211_IFTYPE_P2P_DEVICE:
 897		need_offchan = true;
 898		break;
 899	case NL80211_IFTYPE_NAN:
 900		break;
 901	default:
 902		return -EOPNOTSUPP;
 903	}
 904
 905	/* configurations requiring offchan cannot work if no channel has been
 906	 * specified
 907	 */
 908	if (need_offchan && !params->chan)
 909		return -EINVAL;
 910
 911	/* Check if the operating channel is the requested channel */
 912	if (!params->chan && mlo_sta) {
 913		need_offchan = false;
 914	} else if (sdata->vif.type == NL80211_IFTYPE_NAN) {
 915		/* Frames can be sent during NAN schedule */
 916	} else if (!need_offchan) {
 917		struct ieee80211_chanctx_conf *chanctx_conf = NULL;
 918		int i;
 919
 920		rcu_read_lock();
 921		/* Check all the links first */
 922		for (i = 0; i < ARRAY_SIZE(sdata->vif.link_conf); i++) {
 923			struct ieee80211_bss_conf *conf;
 924
 925			conf = rcu_dereference(sdata->vif.link_conf[i]);
 926			if (!conf)
 927				continue;
 928
 929			chanctx_conf = rcu_dereference(conf->chanctx_conf);
 930			if (!chanctx_conf)
 931				continue;
 932
 933			if (mlo_sta && params->chan == chanctx_conf->def.chan &&
 934			    ether_addr_equal(sdata->vif.addr, mgmt->sa)) {
 935				link_id = i;
 936				break;
 937			}
 938
 939			if (ether_addr_equal(conf->addr, mgmt->sa)) {
 940				/* If userspace requested Tx on a specific link
 941				 * use the same link id if the link bss is matching
 942				 * the requested chan.
 943				 */
 944				if (sdata->vif.valid_links &&
 945				    params->link_id >= 0 && params->link_id == i &&
 946				    params->chan == chanctx_conf->def.chan)
 947					link_id = i;
 948
 949				break;
 950			}
 951
 952			chanctx_conf = NULL;
 953		}
 954
 955		if (chanctx_conf) {
 956			need_offchan = params->chan &&
 957				       (params->chan !=
 958					chanctx_conf->def.chan);
 959		} else {
 960			need_offchan = true;
 961		}
 962		rcu_read_unlock();
 963	}
 964
 965	if (need_offchan && !params->offchan) {
 966		ret = -EBUSY;
 967		goto out_unlock;
 968	}
 969
 970	skb = dev_alloc_skb(local->hw.extra_tx_headroom + params->len);
 971	if (!skb) {
 972		ret = -ENOMEM;
 973		goto out_unlock;
 974	}
 975	skb_reserve(skb, local->hw.extra_tx_headroom);
 976
 977	data = skb_put_data(skb, params->buf, params->len);
 978
 979	/* Update CSA counters */
 980	if (sdata->vif.bss_conf.csa_active &&
 981	    (sdata->vif.type == NL80211_IFTYPE_AP ||
 982	     sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
 983	     sdata->vif.type == NL80211_IFTYPE_ADHOC) &&
 984	    params->n_csa_offsets) {
 985		int i;
 986		struct beacon_data *beacon = NULL;
 987
 988		rcu_read_lock();
 989
 990		if (sdata->vif.type == NL80211_IFTYPE_AP)
 991			beacon = rcu_dereference(sdata->deflink.u.ap.beacon);
 992		else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
 993			beacon = rcu_dereference(sdata->u.ibss.presp);
 994		else if (ieee80211_vif_is_mesh(&sdata->vif))
 995			beacon = rcu_dereference(sdata->u.mesh.beacon);
 996
 997		if (beacon)
 998			for (i = 0; i < params->n_csa_offsets; i++)
 999				data[params->csa_offsets[i]] =
1000					beacon->cntdwn_current_counter;
1001
1002		rcu_read_unlock();
1003	}
1004
1005	IEEE80211_SKB_CB(skb)->flags = flags;
1006	IEEE80211_SKB_CB(skb)->control.flags |= IEEE80211_TX_CTRL_DONT_USE_RATE_MASK;
1007
1008	skb->dev = sdata->dev;
1009
1010	if (!params->dont_wait_for_ack) {
1011		/* make a copy to preserve the frame contents
1012		 * in case of encryption.
1013		 */
1014		ret = ieee80211_attach_ack_skb(local, skb, cookie, GFP_KERNEL);
1015		if (ret) {
1016			kfree_skb(skb);
1017			goto out_unlock;
1018		}
1019	} else {
1020		/* Assign a dummy non-zero cookie, it's not sent to
1021		 * userspace in this case but we rely on its value
1022		 * internally in the need_offchan case to distinguish
1023		 * mgmt-tx from remain-on-channel.
1024		 */
1025		*cookie = 0xffffffff;
1026	}
1027
1028	if (!need_offchan) {
1029		ieee80211_tx_skb_tid(sdata, skb, 7, link_id);
1030		ret = 0;
1031		goto out_unlock;
1032	}
1033
1034	IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_TX_OFFCHAN |
1035					IEEE80211_TX_INTFL_OFFCHAN_TX_OK;
1036	if (ieee80211_hw_check(&local->hw, QUEUE_CONTROL))
1037		IEEE80211_SKB_CB(skb)->hw_queue =
1038			local->hw.offchannel_tx_hw_queue;
1039
1040	/* This will handle all kinds of coalescing and immediate TX */
1041	ret = ieee80211_start_roc_work(local, sdata, params->chan,
1042				       params->wait, cookie, skb,
1043				       IEEE80211_ROC_TYPE_MGMT_TX);
1044	if (ret)
1045		ieee80211_free_txskb(&local->hw, skb);
1046 out_unlock:
1047	return ret;
1048}
1049
1050int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
1051				  struct wireless_dev *wdev, u64 cookie)
1052{
1053	struct ieee80211_local *local = wiphy_priv(wiphy);
1054
1055	return ieee80211_cancel_roc(local, cookie, true);
1056}
1057
1058void ieee80211_roc_setup(struct ieee80211_local *local)
1059{
1060	wiphy_work_init(&local->hw_roc_start, ieee80211_hw_roc_start);
1061	wiphy_work_init(&local->hw_roc_done, ieee80211_hw_roc_done);
1062	wiphy_delayed_work_init(&local->roc_work, ieee80211_roc_work);
1063	INIT_LIST_HEAD(&local->roc_list);
1064}
1065
1066void ieee80211_roc_purge(struct ieee80211_local *local,
1067			 struct ieee80211_sub_if_data *sdata)
1068{
1069	struct ieee80211_roc_work *roc, *tmp;
1070	bool work_to_do = false;
1071
1072	lockdep_assert_wiphy(local->hw.wiphy);
1073
1074	list_for_each_entry_safe(roc, tmp, &local->roc_list, list) {
1075		if (sdata && roc->sdata != sdata)
1076			continue;
1077
1078		if (roc->started) {
1079			if (local->ops->remain_on_channel) {
1080				/* can race, so ignore return value */
1081				drv_cancel_remain_on_channel(local, roc->sdata);
1082				ieee80211_roc_notify_destroy(roc);
1083			} else {
1084				roc->abort = true;
1085				work_to_do = true;
1086			}
1087		} else {
1088			ieee80211_roc_notify_destroy(roc);
1089		}
1090	}
1091	if (work_to_do)
1092		__ieee80211_roc_work(local);
1093}
~/ Read-only file preview.