xref: /linux/drivers/net/wireless/ath/ath9k/channel.c (revision 3932b9ca55b0be314a36d3e84faff3e823c081f5)
1 /*
2  * Copyright (c) 2014 Qualcomm Atheros, Inc.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #include "ath9k.h"
18 
19 /* Set/change channels.  If the channel is really being changed, it's done
20  * by reseting the chip.  To accomplish this we must first cleanup any pending
21  * DMA, then restart stuff.
22  */
23 static int ath_set_channel(struct ath_softc *sc)
24 {
25 	struct ath_hw *ah = sc->sc_ah;
26 	struct ath_common *common = ath9k_hw_common(ah);
27 	struct ieee80211_hw *hw = sc->hw;
28 	struct ath9k_channel *hchan;
29 	struct cfg80211_chan_def *chandef = &sc->cur_chan->chandef;
30 	struct ieee80211_channel *chan = chandef->chan;
31 	int pos = chan->hw_value;
32 	int old_pos = -1;
33 	int r;
34 
35 	if (test_bit(ATH_OP_INVALID, &common->op_flags))
36 		return -EIO;
37 
38 	if (ah->curchan)
39 		old_pos = ah->curchan - &ah->channels[0];
40 
41 	ath_dbg(common, CONFIG, "Set channel: %d MHz width: %d\n",
42 		chan->center_freq, chandef->width);
43 
44 	/* update survey stats for the old channel before switching */
45 	spin_lock_bh(&common->cc_lock);
46 	ath_update_survey_stats(sc);
47 	spin_unlock_bh(&common->cc_lock);
48 
49 	ath9k_cmn_get_channel(hw, ah, chandef);
50 
51 	/* If the operating channel changes, change the survey in-use flags
52 	 * along with it.
53 	 * Reset the survey data for the new channel, unless we're switching
54 	 * back to the operating channel from an off-channel operation.
55 	 */
56 	if (!sc->cur_chan->offchannel && sc->cur_survey != &sc->survey[pos]) {
57 		if (sc->cur_survey)
58 			sc->cur_survey->filled &= ~SURVEY_INFO_IN_USE;
59 
60 		sc->cur_survey = &sc->survey[pos];
61 
62 		memset(sc->cur_survey, 0, sizeof(struct survey_info));
63 		sc->cur_survey->filled |= SURVEY_INFO_IN_USE;
64 	} else if (!(sc->survey[pos].filled & SURVEY_INFO_IN_USE)) {
65 		memset(&sc->survey[pos], 0, sizeof(struct survey_info));
66 	}
67 
68 	hchan = &sc->sc_ah->channels[pos];
69 	r = ath_reset_internal(sc, hchan);
70 	if (r)
71 		return r;
72 
73 	/* The most recent snapshot of channel->noisefloor for the old
74 	 * channel is only available after the hardware reset. Copy it to
75 	 * the survey stats now.
76 	 */
77 	if (old_pos >= 0)
78 		ath_update_survey_nf(sc, old_pos);
79 
80 	/* Enable radar pulse detection if on a DFS channel. Spectral
81 	 * scanning and radar detection can not be used concurrently.
82 	 */
83 	if (hw->conf.radar_enabled) {
84 		u32 rxfilter;
85 
86 		/* set HW specific DFS configuration */
87 		ath9k_hw_set_radar_params(ah);
88 		rxfilter = ath9k_hw_getrxfilter(ah);
89 		rxfilter |= ATH9K_RX_FILTER_PHYRADAR |
90 				ATH9K_RX_FILTER_PHYERR;
91 		ath9k_hw_setrxfilter(ah, rxfilter);
92 		ath_dbg(common, DFS, "DFS enabled at freq %d\n",
93 			chan->center_freq);
94 	} else {
95 		/* perform spectral scan if requested. */
96 		if (test_bit(ATH_OP_SCANNING, &common->op_flags) &&
97 			sc->spectral_mode == SPECTRAL_CHANSCAN)
98 			ath9k_spectral_scan_trigger(hw);
99 	}
100 
101 	return 0;
102 }
103 
104 static bool
105 ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp,
106 			      bool powersave)
107 {
108 	struct ieee80211_vif *vif = avp->vif;
109 	struct ieee80211_sta *sta = NULL;
110 	struct ieee80211_hdr_3addr *nullfunc;
111 	struct ath_tx_control txctl;
112 	struct sk_buff *skb;
113 	int band = sc->cur_chan->chandef.chan->band;
114 
115 	switch (vif->type) {
116 	case NL80211_IFTYPE_STATION:
117 		if (!vif->bss_conf.assoc)
118 			return false;
119 
120 		skb = ieee80211_nullfunc_get(sc->hw, vif);
121 		if (!skb)
122 			return false;
123 
124 		nullfunc = (struct ieee80211_hdr_3addr *) skb->data;
125 		if (powersave)
126 			nullfunc->frame_control |=
127 				cpu_to_le16(IEEE80211_FCTL_PM);
128 
129 		skb_set_queue_mapping(skb, IEEE80211_AC_VO);
130 		if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta)) {
131 			dev_kfree_skb_any(skb);
132 			return false;
133 		}
134 		break;
135 	default:
136 		return false;
137 	}
138 
139 	memset(&txctl, 0, sizeof(txctl));
140 	txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];
141 	txctl.sta = sta;
142 	txctl.force_channel = true;
143 	if (ath_tx_start(sc->hw, skb, &txctl)) {
144 		ieee80211_free_txskb(sc->hw, skb);
145 		return false;
146 	}
147 
148 	return true;
149 }
150 
151 void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx)
152 {
153 	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
154 	struct ath_vif *avp;
155 	bool active = false;
156 	u8 n_active = 0;
157 
158 	if (!ctx)
159 		return;
160 
161 	list_for_each_entry(avp, &ctx->vifs, list) {
162 		struct ieee80211_vif *vif = avp->vif;
163 
164 		switch (vif->type) {
165 		case NL80211_IFTYPE_P2P_CLIENT:
166 		case NL80211_IFTYPE_STATION:
167 			if (vif->bss_conf.assoc)
168 				active = true;
169 			break;
170 		default:
171 			active = true;
172 			break;
173 		}
174 	}
175 	ctx->active = active;
176 
177 	ath_for_each_chanctx(sc, ctx) {
178 		if (!ctx->assigned || list_empty(&ctx->vifs))
179 			continue;
180 		n_active++;
181 	}
182 
183 	if (n_active <= 1) {
184 		clear_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags);
185 		return;
186 	}
187 	if (test_and_set_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags))
188 		return;
189 	ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_ENABLE_MULTICHANNEL);
190 }
191 
192 static bool
193 ath_chanctx_send_ps_frame(struct ath_softc *sc, bool powersave)
194 {
195 	struct ath_vif *avp;
196 	bool sent = false;
197 
198 	rcu_read_lock();
199 	list_for_each_entry(avp, &sc->cur_chan->vifs, list) {
200 		if (ath_chanctx_send_vif_ps_frame(sc, avp, powersave))
201 			sent = true;
202 	}
203 	rcu_read_unlock();
204 
205 	return sent;
206 }
207 
208 static bool ath_chanctx_defer_switch(struct ath_softc *sc)
209 {
210 	if (sc->cur_chan == &sc->offchannel.chan)
211 		return false;
212 
213 	switch (sc->sched.state) {
214 	case ATH_CHANCTX_STATE_SWITCH:
215 		return false;
216 	case ATH_CHANCTX_STATE_IDLE:
217 		if (!sc->cur_chan->switch_after_beacon)
218 			return false;
219 
220 		sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON;
221 		break;
222 	default:
223 		break;
224 	}
225 
226 	return true;
227 }
228 
229 static void ath_chanctx_set_next(struct ath_softc *sc, bool force)
230 {
231 	struct timespec ts;
232 	bool measure_time = false;
233 	bool send_ps = false;
234 
235 	spin_lock_bh(&sc->chan_lock);
236 	if (!sc->next_chan) {
237 		spin_unlock_bh(&sc->chan_lock);
238 		return;
239 	}
240 
241 	if (!force && ath_chanctx_defer_switch(sc)) {
242 		spin_unlock_bh(&sc->chan_lock);
243 		return;
244 	}
245 
246 	if (sc->cur_chan != sc->next_chan) {
247 		sc->cur_chan->stopped = true;
248 		spin_unlock_bh(&sc->chan_lock);
249 
250 		if (sc->next_chan == &sc->offchannel.chan) {
251 			getrawmonotonic(&ts);
252 			measure_time = true;
253 		}
254 		__ath9k_flush(sc->hw, ~0, true);
255 
256 		if (ath_chanctx_send_ps_frame(sc, true))
257 			__ath9k_flush(sc->hw, BIT(IEEE80211_AC_VO), false);
258 
259 		send_ps = true;
260 		spin_lock_bh(&sc->chan_lock);
261 
262 		if (sc->cur_chan != &sc->offchannel.chan) {
263 			getrawmonotonic(&sc->cur_chan->tsf_ts);
264 			sc->cur_chan->tsf_val = ath9k_hw_gettsf64(sc->sc_ah);
265 		}
266 	}
267 	sc->cur_chan = sc->next_chan;
268 	sc->cur_chan->stopped = false;
269 	sc->next_chan = NULL;
270 	sc->sched.offchannel_duration = 0;
271 	if (sc->sched.state != ATH_CHANCTX_STATE_FORCE_ACTIVE)
272 		sc->sched.state = ATH_CHANCTX_STATE_IDLE;
273 
274 	spin_unlock_bh(&sc->chan_lock);
275 
276 	if (sc->sc_ah->chip_fullsleep ||
277 	    memcmp(&sc->cur_chandef, &sc->cur_chan->chandef,
278 		   sizeof(sc->cur_chandef))) {
279 		ath_set_channel(sc);
280 		if (measure_time)
281 			sc->sched.channel_switch_time =
282 				ath9k_hw_get_tsf_offset(&ts, NULL);
283 	}
284 	if (send_ps)
285 		ath_chanctx_send_ps_frame(sc, false);
286 
287 	ath_offchannel_channel_change(sc);
288 	ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_SWITCH);
289 }
290 
291 void ath_chanctx_work(struct work_struct *work)
292 {
293 	struct ath_softc *sc = container_of(work, struct ath_softc,
294 					    chanctx_work);
295 	mutex_lock(&sc->mutex);
296 	ath_chanctx_set_next(sc, false);
297 	mutex_unlock(&sc->mutex);
298 }
299 
300 void ath_chanctx_init(struct ath_softc *sc)
301 {
302 	struct ath_chanctx *ctx;
303 	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
304 	struct ieee80211_supported_band *sband;
305 	struct ieee80211_channel *chan;
306 	int i, j;
307 
308 	sband = &common->sbands[IEEE80211_BAND_2GHZ];
309 	if (!sband->n_channels)
310 		sband = &common->sbands[IEEE80211_BAND_5GHZ];
311 
312 	chan = &sband->channels[0];
313 	for (i = 0; i < ATH9K_NUM_CHANCTX; i++) {
314 		ctx = &sc->chanctx[i];
315 		cfg80211_chandef_create(&ctx->chandef, chan, NL80211_CHAN_HT20);
316 		INIT_LIST_HEAD(&ctx->vifs);
317 		ctx->txpower = ATH_TXPOWER_MAX;
318 		for (j = 0; j < ARRAY_SIZE(ctx->acq); j++)
319 			INIT_LIST_HEAD(&ctx->acq[j]);
320 	}
321 	ctx = &sc->offchannel.chan;
322 	cfg80211_chandef_create(&ctx->chandef, chan, NL80211_CHAN_HT20);
323 	INIT_LIST_HEAD(&ctx->vifs);
324 	ctx->txpower = ATH_TXPOWER_MAX;
325 	for (j = 0; j < ARRAY_SIZE(ctx->acq); j++)
326 		INIT_LIST_HEAD(&ctx->acq[j]);
327 	sc->offchannel.chan.offchannel = true;
328 
329 }
330 
331 void ath9k_chanctx_force_active(struct ieee80211_hw *hw,
332 				struct ieee80211_vif *vif)
333 {
334 	struct ath_softc *sc = hw->priv;
335 	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
336 	struct ath_vif *avp = (struct ath_vif *) vif->drv_priv;
337 	bool changed = false;
338 
339 	if (!test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags))
340 		return;
341 
342 	if (!avp->chanctx)
343 		return;
344 
345 	mutex_lock(&sc->mutex);
346 
347 	spin_lock_bh(&sc->chan_lock);
348 	if (sc->next_chan || (sc->cur_chan != avp->chanctx)) {
349 		sc->next_chan = avp->chanctx;
350 		changed = true;
351 	}
352 	sc->sched.state = ATH_CHANCTX_STATE_FORCE_ACTIVE;
353 	spin_unlock_bh(&sc->chan_lock);
354 
355 	if (changed)
356 		ath_chanctx_set_next(sc, true);
357 
358 	mutex_unlock(&sc->mutex);
359 }
360 
361 void ath_chanctx_switch(struct ath_softc *sc, struct ath_chanctx *ctx,
362 			struct cfg80211_chan_def *chandef)
363 {
364 	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
365 
366 	spin_lock_bh(&sc->chan_lock);
367 
368 	if (test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags) &&
369 	    (sc->cur_chan != ctx) && (ctx == &sc->offchannel.chan)) {
370 		sc->sched.offchannel_pending = true;
371 		spin_unlock_bh(&sc->chan_lock);
372 		return;
373 	}
374 
375 	sc->next_chan = ctx;
376 	if (chandef)
377 		ctx->chandef = *chandef;
378 
379 	if (sc->next_chan == &sc->offchannel.chan) {
380 		sc->sched.offchannel_duration =
381 			TU_TO_USEC(sc->offchannel.duration) +
382 			sc->sched.channel_switch_time;
383 	}
384 	spin_unlock_bh(&sc->chan_lock);
385 	ieee80211_queue_work(sc->hw, &sc->chanctx_work);
386 }
387 
388 void ath_chanctx_set_channel(struct ath_softc *sc, struct ath_chanctx *ctx,
389 			     struct cfg80211_chan_def *chandef)
390 {
391 	bool cur_chan;
392 
393 	spin_lock_bh(&sc->chan_lock);
394 	if (chandef)
395 		memcpy(&ctx->chandef, chandef, sizeof(*chandef));
396 	cur_chan = sc->cur_chan == ctx;
397 	spin_unlock_bh(&sc->chan_lock);
398 
399 	if (!cur_chan)
400 		return;
401 
402 	ath_set_channel(sc);
403 }
404 
405 struct ath_chanctx *ath_chanctx_get_oper_chan(struct ath_softc *sc, bool active)
406 {
407 	struct ath_chanctx *ctx;
408 
409 	ath_for_each_chanctx(sc, ctx) {
410 		if (!ctx->assigned || list_empty(&ctx->vifs))
411 			continue;
412 		if (active && !ctx->active)
413 			continue;
414 
415 		if (ctx->switch_after_beacon)
416 			return ctx;
417 	}
418 
419 	return &sc->chanctx[0];
420 }
421 
422 void ath_chanctx_offchan_switch(struct ath_softc *sc,
423 				struct ieee80211_channel *chan)
424 {
425 	struct cfg80211_chan_def chandef;
426 
427 	cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);
428 
429 	ath_chanctx_switch(sc, &sc->offchannel.chan, &chandef);
430 }
431 
432 static struct ath_chanctx *
433 ath_chanctx_get_next(struct ath_softc *sc, struct ath_chanctx *ctx)
434 {
435 	int idx = ctx - &sc->chanctx[0];
436 
437 	return &sc->chanctx[!idx];
438 }
439 
440 static void ath_chanctx_adjust_tbtt_delta(struct ath_softc *sc)
441 {
442 	struct ath_chanctx *prev, *cur;
443 	struct timespec ts;
444 	u32 cur_tsf, prev_tsf, beacon_int;
445 	s32 offset;
446 
447 	beacon_int = TU_TO_USEC(sc->cur_chan->beacon.beacon_interval);
448 
449 	cur = sc->cur_chan;
450 	prev = ath_chanctx_get_next(sc, cur);
451 
452 	getrawmonotonic(&ts);
453 	cur_tsf = (u32) cur->tsf_val +
454 		  ath9k_hw_get_tsf_offset(&cur->tsf_ts, &ts);
455 
456 	prev_tsf = prev->last_beacon - (u32) prev->tsf_val + cur_tsf;
457 	prev_tsf -= ath9k_hw_get_tsf_offset(&prev->tsf_ts, &ts);
458 
459 	/* Adjust the TSF time of the AP chanctx to keep its beacons
460 	 * at half beacon interval offset relative to the STA chanctx.
461 	 */
462 	offset = cur_tsf - prev_tsf;
463 
464 	/* Ignore stale data or spurious timestamps */
465 	if (offset < 0 || offset > 3 * beacon_int)
466 		return;
467 
468 	offset = beacon_int / 2 - (offset % beacon_int);
469 	prev->tsf_val += offset;
470 }
471 
472 void ath_chanctx_timer(unsigned long data)
473 {
474 	struct ath_softc *sc = (struct ath_softc *) data;
475 
476 	ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_TSF_TIMER);
477 }
478 
479 /* Configure the TSF based hardware timer for a channel switch.
480  * Also set up backup software timer, in case the gen timer fails.
481  * This could be caused by a hardware reset.
482  */
483 static void ath_chanctx_setup_timer(struct ath_softc *sc, u32 tsf_time)
484 {
485 	struct ath_hw *ah = sc->sc_ah;
486 
487 	ath9k_hw_gen_timer_start(ah, sc->p2p_ps_timer, tsf_time, 1000000);
488 	tsf_time -= ath9k_hw_gettsf32(ah);
489 	tsf_time = msecs_to_jiffies(tsf_time / 1000) + 1;
490 	mod_timer(&sc->sched.timer, tsf_time);
491 }
492 
493 void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif,
494 		       enum ath_chanctx_event ev)
495 {
496 	struct ath_hw *ah = sc->sc_ah;
497 	struct ath_common *common = ath9k_hw_common(ah);
498 	struct ath_beacon_config *cur_conf;
499 	struct ath_vif *avp = NULL;
500 	struct ath_chanctx *ctx;
501 	u32 tsf_time;
502 	u32 beacon_int;
503 	bool noa_changed = false;
504 
505 	if (vif)
506 		avp = (struct ath_vif *) vif->drv_priv;
507 
508 	spin_lock_bh(&sc->chan_lock);
509 
510 	switch (ev) {
511 	case ATH_CHANCTX_EVENT_BEACON_PREPARE:
512 		if (avp->offchannel_duration)
513 			avp->offchannel_duration = 0;
514 
515 		if (avp->chanctx != sc->cur_chan)
516 			break;
517 
518 		if (sc->sched.offchannel_pending) {
519 			sc->sched.offchannel_pending = false;
520 			sc->next_chan = &sc->offchannel.chan;
521 			sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON;
522 		}
523 
524 		ctx = ath_chanctx_get_next(sc, sc->cur_chan);
525 		if (ctx->active && sc->sched.state == ATH_CHANCTX_STATE_IDLE) {
526 			sc->next_chan = ctx;
527 			sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON;
528 		}
529 
530 		/* if the timer missed its window, use the next interval */
531 		if (sc->sched.state == ATH_CHANCTX_STATE_WAIT_FOR_TIMER)
532 			sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON;
533 
534 		if (sc->sched.state != ATH_CHANCTX_STATE_WAIT_FOR_BEACON)
535 			break;
536 
537 		sc->sched.beacon_pending = true;
538 		sc->sched.next_tbtt = REG_READ(ah, AR_NEXT_TBTT_TIMER);
539 
540 		cur_conf = &sc->cur_chan->beacon;
541 		beacon_int = TU_TO_USEC(cur_conf->beacon_interval);
542 
543 		/* defer channel switch by a quarter beacon interval */
544 		tsf_time = sc->sched.next_tbtt + beacon_int / 4;
545 		sc->sched.switch_start_time = tsf_time;
546 		sc->cur_chan->last_beacon = sc->sched.next_tbtt;
547 
548 		/* Prevent wrap-around issues */
549 		if (avp->periodic_noa_duration &&
550 		    tsf_time - avp->periodic_noa_start > BIT(30))
551 			avp->periodic_noa_duration = 0;
552 
553 		if (ctx->active && !avp->periodic_noa_duration) {
554 			avp->periodic_noa_start = tsf_time;
555 			avp->periodic_noa_duration =
556 				TU_TO_USEC(cur_conf->beacon_interval) / 2 -
557 				sc->sched.channel_switch_time;
558 			noa_changed = true;
559 		} else if (!ctx->active && avp->periodic_noa_duration) {
560 			avp->periodic_noa_duration = 0;
561 			noa_changed = true;
562 		}
563 
564 		/* If at least two consecutive beacons were missed on the STA
565 		 * chanctx, stay on the STA channel for one extra beacon period,
566 		 * to resync the timer properly.
567 		 */
568 		if (ctx->active && sc->sched.beacon_miss >= 2)
569 			sc->sched.offchannel_duration = 3 * beacon_int / 2;
570 
571 		if (sc->sched.offchannel_duration) {
572 			noa_changed = true;
573 			avp->offchannel_start = tsf_time;
574 			avp->offchannel_duration =
575 				sc->sched.offchannel_duration;
576 		}
577 
578 		if (noa_changed)
579 			avp->noa_index++;
580 		break;
581 	case ATH_CHANCTX_EVENT_BEACON_SENT:
582 		if (!sc->sched.beacon_pending)
583 			break;
584 
585 		sc->sched.beacon_pending = false;
586 		if (sc->sched.state != ATH_CHANCTX_STATE_WAIT_FOR_BEACON)
587 			break;
588 
589 		sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_TIMER;
590 		ath_chanctx_setup_timer(sc, sc->sched.switch_start_time);
591 		break;
592 	case ATH_CHANCTX_EVENT_TSF_TIMER:
593 		if (sc->sched.state != ATH_CHANCTX_STATE_WAIT_FOR_TIMER)
594 			break;
595 
596 		if (!sc->cur_chan->switch_after_beacon &&
597 		    sc->sched.beacon_pending)
598 			sc->sched.beacon_miss++;
599 
600 		sc->sched.state = ATH_CHANCTX_STATE_SWITCH;
601 		ieee80211_queue_work(sc->hw, &sc->chanctx_work);
602 		break;
603 	case ATH_CHANCTX_EVENT_BEACON_RECEIVED:
604 		if (!test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags) ||
605 		    sc->cur_chan == &sc->offchannel.chan)
606 			break;
607 
608 		ath_chanctx_adjust_tbtt_delta(sc);
609 		sc->sched.beacon_pending = false;
610 		sc->sched.beacon_miss = 0;
611 
612 		/* TSF time might have been updated by the incoming beacon,
613 		 * need update the channel switch timer to reflect the change.
614 		 */
615 		tsf_time = sc->sched.switch_start_time;
616 		tsf_time -= (u32) sc->cur_chan->tsf_val +
617 			ath9k_hw_get_tsf_offset(&sc->cur_chan->tsf_ts, NULL);
618 		tsf_time += ath9k_hw_gettsf32(ah);
619 
620 
621 		ath_chanctx_setup_timer(sc, tsf_time);
622 		break;
623 	case ATH_CHANCTX_EVENT_ASSOC:
624 		if (sc->sched.state != ATH_CHANCTX_STATE_FORCE_ACTIVE ||
625 		    avp->chanctx != sc->cur_chan)
626 			break;
627 
628 		sc->sched.state = ATH_CHANCTX_STATE_IDLE;
629 		/* fall through */
630 	case ATH_CHANCTX_EVENT_SWITCH:
631 		if (!test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags) ||
632 		    sc->sched.state == ATH_CHANCTX_STATE_FORCE_ACTIVE ||
633 		    sc->cur_chan->switch_after_beacon ||
634 		    sc->cur_chan == &sc->offchannel.chan)
635 			break;
636 
637 		/* If this is a station chanctx, stay active for a half
638 		 * beacon period (minus channel switch time)
639 		 */
640 		sc->next_chan = ath_chanctx_get_next(sc, sc->cur_chan);
641 		cur_conf = &sc->cur_chan->beacon;
642 
643 		sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_TIMER;
644 
645 		tsf_time = TU_TO_USEC(cur_conf->beacon_interval) / 2;
646 		if (sc->sched.beacon_miss >= 2) {
647 			sc->sched.beacon_miss = 0;
648 			tsf_time *= 3;
649 		}
650 
651 		tsf_time -= sc->sched.channel_switch_time;
652 		tsf_time += ath9k_hw_gettsf32(sc->sc_ah);
653 		sc->sched.switch_start_time = tsf_time;
654 
655 		ath_chanctx_setup_timer(sc, tsf_time);
656 		sc->sched.beacon_pending = true;
657 		break;
658 	case ATH_CHANCTX_EVENT_ENABLE_MULTICHANNEL:
659 		if (sc->cur_chan == &sc->offchannel.chan ||
660 		    sc->cur_chan->switch_after_beacon)
661 			break;
662 
663 		sc->next_chan = ath_chanctx_get_next(sc, sc->cur_chan);
664 		ieee80211_queue_work(sc->hw, &sc->chanctx_work);
665 		break;
666 	case ATH_CHANCTX_EVENT_UNASSIGN:
667 		if (sc->cur_chan->assigned) {
668 			if (sc->next_chan && !sc->next_chan->assigned &&
669 			    sc->next_chan != &sc->offchannel.chan)
670 				sc->sched.state = ATH_CHANCTX_STATE_IDLE;
671 			break;
672 		}
673 
674 		ctx = ath_chanctx_get_next(sc, sc->cur_chan);
675 		sc->sched.state = ATH_CHANCTX_STATE_IDLE;
676 		if (!ctx->assigned)
677 			break;
678 
679 		sc->next_chan = ctx;
680 		ieee80211_queue_work(sc->hw, &sc->chanctx_work);
681 		break;
682 	}
683 
684 	spin_unlock_bh(&sc->chan_lock);
685 }
686