brintos

brintos / linux-shallow public Read only

0
0
Text · 42.1 KiB · 571062f Raw
1652 lines · c
1/*2 * Copyright (c) 2014 Qualcomm Atheros, Inc.3 *4 * Permission to use, copy, modify, and/or distribute this software for any5 * purpose with or without fee is hereby granted, provided that the above6 * copyright notice and this permission notice appear in all copies.7 *8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF14 * 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 done20 * by reseting the chip.  To accomplish this we must first cleanup any pending21 * DMA, then restart stuff.22 */23static 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	unsigned long flags;33	int old_pos = -1;34	int r;35 36	if (test_bit(ATH_OP_INVALID, &common->op_flags))37		return -EIO;38 39	if (ah->curchan)40		old_pos = ah->curchan - &ah->channels[0];41 42	ath_dbg(common, CONFIG, "Set channel: %d MHz width: %d\n",43		chan->center_freq, chandef->width);44 45	/* update survey stats for the old channel before switching */46	spin_lock_irqsave(&common->cc_lock, flags);47	ath_update_survey_stats(sc);48	spin_unlock_irqrestore(&common->cc_lock, flags);49 50	ath9k_cmn_get_channel(hw, ah, chandef);51 52	/* If the operating channel changes, change the survey in-use flags53	 * along with it.54	 * Reset the survey data for the new channel, unless we're switching55	 * back to the operating channel from an off-channel operation.56	 */57	if (!sc->cur_chan->offchannel && sc->cur_survey != &sc->survey[pos]) {58		if (sc->cur_survey)59			sc->cur_survey->filled &= ~SURVEY_INFO_IN_USE;60 61		sc->cur_survey = &sc->survey[pos];62 63		memset(sc->cur_survey, 0, sizeof(struct survey_info));64		sc->cur_survey->filled |= SURVEY_INFO_IN_USE;65	} else if (!(sc->survey[pos].filled & SURVEY_INFO_IN_USE)) {66		memset(&sc->survey[pos], 0, sizeof(struct survey_info));67	}68 69	hchan = &sc->sc_ah->channels[pos];70	r = ath_reset(sc, hchan);71	if (r)72		return r;73 74	/* The most recent snapshot of channel->noisefloor for the old75	 * channel is only available after the hardware reset. Copy it to76	 * the survey stats now.77	 */78	if (old_pos >= 0)79		ath_update_survey_nf(sc, old_pos);80 81	/* Enable radar pulse detection if on a DFS channel. Spectral82	 * scanning and radar detection can not be used concurrently.83	 */84	if (hw->conf.radar_enabled) {85		u32 rxfilter;86 87		rxfilter = ath9k_hw_getrxfilter(ah);88		rxfilter |= ATH9K_RX_FILTER_PHYRADAR |89				ATH9K_RX_FILTER_PHYERR;90		ath9k_hw_setrxfilter(ah, rxfilter);91		ath_dbg(common, DFS, "DFS enabled at freq %d\n",92			chan->center_freq);93	} else {94		/* perform spectral scan if requested. */95		if (test_bit(ATH_OP_SCANNING, &common->op_flags) &&96			sc->spec_priv.spectral_mode == SPECTRAL_CHANSCAN)97			ath9k_cmn_spectral_scan_trigger(common, &sc->spec_priv);98	}99 100	return 0;101}102 103void ath_chanctx_init(struct ath_softc *sc)104{105	struct ath_chanctx *ctx;106	struct ath_common *common = ath9k_hw_common(sc->sc_ah);107	struct ieee80211_supported_band *sband;108	struct ieee80211_channel *chan;109	int i, j;110 111	sband = &common->sbands[NL80211_BAND_2GHZ];112	if (!sband->n_channels)113		sband = &common->sbands[NL80211_BAND_5GHZ];114 115	chan = &sband->channels[0];116	for (i = 0; i < ATH9K_NUM_CHANCTX; i++) {117		ctx = &sc->chanctx[i];118		cfg80211_chandef_create(&ctx->chandef, chan, NL80211_CHAN_HT20);119		INIT_LIST_HEAD(&ctx->vifs);120		ctx->txpower = ATH_TXPOWER_MAX;121		ctx->flush_timeout = HZ / 5; /* 200ms */122		for (j = 0; j < ARRAY_SIZE(ctx->acq); j++) {123			INIT_LIST_HEAD(&ctx->acq[j].acq_new);124			INIT_LIST_HEAD(&ctx->acq[j].acq_old);125			spin_lock_init(&ctx->acq[j].lock);126		}127	}128}129 130void ath_chanctx_set_channel(struct ath_softc *sc, struct ath_chanctx *ctx,131			     struct cfg80211_chan_def *chandef)132{133	struct ath_common *common = ath9k_hw_common(sc->sc_ah);134	bool cur_chan;135 136	spin_lock_bh(&sc->chan_lock);137	if (chandef)138		memcpy(&ctx->chandef, chandef, sizeof(*chandef));139	cur_chan = sc->cur_chan == ctx;140	spin_unlock_bh(&sc->chan_lock);141 142	if (!cur_chan) {143		ath_dbg(common, CHAN_CTX,144			"Current context differs from the new context\n");145		return;146	}147 148	ath_set_channel(sc);149}150 151#ifdef CONFIG_ATH9K_CHANNEL_CONTEXT152 153/*************/154/* Utilities */155/*************/156 157struct ath_chanctx* ath_is_go_chanctx_present(struct ath_softc *sc)158{159	struct ath_chanctx *ctx;160	struct ath_vif *avp;161	struct ieee80211_vif *vif;162 163	spin_lock_bh(&sc->chan_lock);164 165	ath_for_each_chanctx(sc, ctx) {166		if (!ctx->active)167			continue;168 169		list_for_each_entry(avp, &ctx->vifs, list) {170			vif = avp->vif;171 172			if (ieee80211_vif_type_p2p(vif) == NL80211_IFTYPE_P2P_GO) {173				spin_unlock_bh(&sc->chan_lock);174				return ctx;175			}176		}177	}178 179	spin_unlock_bh(&sc->chan_lock);180	return NULL;181}182 183/**********************************************************/184/* Functions to handle the channel context state machine. */185/**********************************************************/186 187static const char *offchannel_state_string(enum ath_offchannel_state state)188{189	switch (state) {190		case_rtn_string(ATH_OFFCHANNEL_IDLE);191		case_rtn_string(ATH_OFFCHANNEL_PROBE_SEND);192		case_rtn_string(ATH_OFFCHANNEL_PROBE_WAIT);193		case_rtn_string(ATH_OFFCHANNEL_SUSPEND);194		case_rtn_string(ATH_OFFCHANNEL_ROC_START);195		case_rtn_string(ATH_OFFCHANNEL_ROC_WAIT);196		case_rtn_string(ATH_OFFCHANNEL_ROC_DONE);197	default:198		return "unknown";199	}200}201 202static const char *chanctx_event_string(enum ath_chanctx_event ev)203{204	switch (ev) {205		case_rtn_string(ATH_CHANCTX_EVENT_BEACON_PREPARE);206		case_rtn_string(ATH_CHANCTX_EVENT_BEACON_SENT);207		case_rtn_string(ATH_CHANCTX_EVENT_TSF_TIMER);208		case_rtn_string(ATH_CHANCTX_EVENT_BEACON_RECEIVED);209		case_rtn_string(ATH_CHANCTX_EVENT_AUTHORIZED);210		case_rtn_string(ATH_CHANCTX_EVENT_SWITCH);211		case_rtn_string(ATH_CHANCTX_EVENT_ASSIGN);212		case_rtn_string(ATH_CHANCTX_EVENT_UNASSIGN);213		case_rtn_string(ATH_CHANCTX_EVENT_CHANGE);214		case_rtn_string(ATH_CHANCTX_EVENT_ENABLE_MULTICHANNEL);215	default:216		return "unknown";217	}218}219 220static const char *chanctx_state_string(enum ath_chanctx_state state)221{222	switch (state) {223		case_rtn_string(ATH_CHANCTX_STATE_IDLE);224		case_rtn_string(ATH_CHANCTX_STATE_WAIT_FOR_BEACON);225		case_rtn_string(ATH_CHANCTX_STATE_WAIT_FOR_TIMER);226		case_rtn_string(ATH_CHANCTX_STATE_SWITCH);227		case_rtn_string(ATH_CHANCTX_STATE_FORCE_ACTIVE);228	default:229		return "unknown";230	}231}232 233static u32 chanctx_event_delta(struct ath_softc *sc)234{235	u64 ms;236	struct timespec64 ts, *old;237 238	ktime_get_raw_ts64(&ts);239	old = &sc->last_event_time;240	ms = ts.tv_sec * 1000 + ts.tv_nsec / 1000000;241	ms -= old->tv_sec * 1000 + old->tv_nsec / 1000000;242	sc->last_event_time = ts;243 244	return (u32)ms;245}246 247void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx)248{249	struct ath_common *common = ath9k_hw_common(sc->sc_ah);250	struct ath_chanctx *ictx;251	struct ath_vif *avp;252	bool active = false;253	u8 n_active = 0;254 255	if (!ctx)256		return;257 258	if (ctx == &sc->offchannel.chan) {259		spin_lock_bh(&sc->chan_lock);260 261		if (likely(sc->sched.channel_switch_time))262			ctx->flush_timeout =263				usecs_to_jiffies(sc->sched.channel_switch_time);264		else265			ctx->flush_timeout =266				msecs_to_jiffies(10);267 268		spin_unlock_bh(&sc->chan_lock);269 270		/*271		 * There is no need to iterate over the272		 * active/assigned channel contexts if273		 * the current context is offchannel.274		 */275		return;276	}277 278	ictx = ctx;279 280	list_for_each_entry(avp, &ctx->vifs, list) {281		struct ieee80211_vif *vif = avp->vif;282 283		switch (vif->type) {284		case NL80211_IFTYPE_P2P_CLIENT:285		case NL80211_IFTYPE_STATION:286			if (avp->assoc)287				active = true;288			break;289		default:290			active = true;291			break;292		}293	}294	ctx->active = active;295 296	ath_for_each_chanctx(sc, ctx) {297		if (!ctx->assigned || list_empty(&ctx->vifs))298			continue;299		n_active++;300	}301 302	spin_lock_bh(&sc->chan_lock);303 304	if (n_active <= 1) {305		ictx->flush_timeout = HZ / 5;306		clear_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags);307		spin_unlock_bh(&sc->chan_lock);308		return;309	}310 311	ictx->flush_timeout = usecs_to_jiffies(sc->sched.channel_switch_time);312 313	if (test_and_set_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags)) {314		spin_unlock_bh(&sc->chan_lock);315		return;316	}317 318	spin_unlock_bh(&sc->chan_lock);319 320	if (ath9k_is_chanctx_enabled()) {321		ath_chanctx_event(sc, NULL,322				  ATH_CHANCTX_EVENT_ENABLE_MULTICHANNEL);323	}324}325 326static struct ath_chanctx *327ath_chanctx_get_next(struct ath_softc *sc, struct ath_chanctx *ctx)328{329	int idx = ctx - &sc->chanctx[0];330 331	return &sc->chanctx[!idx];332}333 334static void ath_chanctx_adjust_tbtt_delta(struct ath_softc *sc)335{336	struct ath_chanctx *prev, *cur;337	struct timespec64 ts;338	u32 cur_tsf, prev_tsf, beacon_int;339	s32 offset;340 341	beacon_int = TU_TO_USEC(sc->cur_chan->beacon.beacon_interval);342 343	cur = sc->cur_chan;344	prev = ath_chanctx_get_next(sc, cur);345 346	if (!prev->switch_after_beacon)347		return;348 349	ktime_get_raw_ts64(&ts);350	cur_tsf = (u32) cur->tsf_val +351		  ath9k_hw_get_tsf_offset(&cur->tsf_ts, &ts);352 353	prev_tsf = prev->last_beacon - (u32) prev->tsf_val + cur_tsf;354	prev_tsf -= ath9k_hw_get_tsf_offset(&prev->tsf_ts, &ts);355 356	/* Adjust the TSF time of the AP chanctx to keep its beacons357	 * at half beacon interval offset relative to the STA chanctx.358	 */359	offset = cur_tsf - prev_tsf;360 361	/* Ignore stale data or spurious timestamps */362	if (offset < 0 || offset > 3 * beacon_int)363		return;364 365	offset = beacon_int / 2 - (offset % beacon_int);366	prev->tsf_val += offset;367}368 369/* Configure the TSF based hardware timer for a channel switch.370 * Also set up backup software timer, in case the gen timer fails.371 * This could be caused by a hardware reset.372 */373static void ath_chanctx_setup_timer(struct ath_softc *sc, u32 tsf_time)374{375	struct ath_common *common = ath9k_hw_common(sc->sc_ah);376	struct ath_hw *ah = sc->sc_ah;377	unsigned long timeout;378 379	ath9k_hw_gen_timer_start(ah, sc->p2p_ps_timer, tsf_time, 1000000);380	tsf_time -= ath9k_hw_gettsf32(ah);381	timeout = msecs_to_jiffies(tsf_time / 1000) + 1;382	mod_timer(&sc->sched.timer, jiffies + timeout);383 384	ath_dbg(common, CHAN_CTX,385		"Setup chanctx timer with timeout: %d (%d) ms\n",386		tsf_time / 1000, jiffies_to_msecs(timeout));387}388 389static void ath_chanctx_handle_bmiss(struct ath_softc *sc,390				     struct ath_chanctx *ctx,391				     struct ath_vif *avp)392{393	/*394	 * Clear the extend_absence flag if it had been395	 * set during the previous beacon transmission,396	 * since we need to revert to the normal NoA397	 * schedule.398	 */399	if (ctx->active && sc->sched.extend_absence) {400		avp->noa_duration = 0;401		sc->sched.extend_absence = false;402	}403 404	/* If at least two consecutive beacons were missed on the STA405	 * chanctx, stay on the STA channel for one extra beacon period,406	 * to resync the timer properly.407	 */408	if (ctx->active && sc->sched.beacon_miss >= 2) {409		avp->noa_duration = 0;410		sc->sched.extend_absence = true;411	}412}413 414static void ath_chanctx_offchannel_noa(struct ath_softc *sc,415				       struct ath_chanctx *ctx,416				       struct ath_vif *avp,417				       u32 tsf_time)418{419	struct ath_common *common = ath9k_hw_common(sc->sc_ah);420 421	avp->noa_index++;422	avp->offchannel_start = tsf_time;423	avp->offchannel_duration = sc->sched.offchannel_duration;424 425	ath_dbg(common, CHAN_CTX,426		"offchannel noa_duration: %d, noa_start: %u, noa_index: %d\n",427		avp->offchannel_duration,428		avp->offchannel_start,429		avp->noa_index);430 431	/*432	 * When multiple contexts are active, the NoA433	 * has to be recalculated and advertised after434	 * an offchannel operation.435	 */436	if (ctx->active && avp->noa_duration)437		avp->noa_duration = 0;438}439 440static void ath_chanctx_set_periodic_noa(struct ath_softc *sc,441					 struct ath_vif *avp,442					 struct ath_beacon_config *cur_conf,443					 u32 tsf_time,444					 u32 beacon_int)445{446	struct ath_common *common = ath9k_hw_common(sc->sc_ah);447 448	avp->noa_index++;449	avp->noa_start = tsf_time;450 451	if (sc->sched.extend_absence)452		avp->noa_duration = (3 * beacon_int / 2) +453			sc->sched.channel_switch_time;454	else455		avp->noa_duration =456			TU_TO_USEC(cur_conf->beacon_interval) / 2 +457			sc->sched.channel_switch_time;458 459	if (test_bit(ATH_OP_SCANNING, &common->op_flags) ||460	    sc->sched.extend_absence)461		avp->periodic_noa = false;462	else463		avp->periodic_noa = true;464 465	ath_dbg(common, CHAN_CTX,466		"noa_duration: %d, noa_start: %u, noa_index: %d, periodic: %d\n",467		avp->noa_duration,468		avp->noa_start,469		avp->noa_index,470		avp->periodic_noa);471}472 473static void ath_chanctx_set_oneshot_noa(struct ath_softc *sc,474					struct ath_vif *avp,475					u32 tsf_time,476					u32 duration)477{478	struct ath_common *common = ath9k_hw_common(sc->sc_ah);479 480	avp->noa_index++;481	avp->noa_start = tsf_time;482	avp->periodic_noa = false;483	avp->oneshot_noa = true;484	avp->noa_duration = duration + sc->sched.channel_switch_time;485 486	ath_dbg(common, CHAN_CTX,487		"oneshot noa_duration: %d, noa_start: %u, noa_index: %d, periodic: %d\n",488		avp->noa_duration,489		avp->noa_start,490		avp->noa_index,491		avp->periodic_noa);492}493 494void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif,495		       enum ath_chanctx_event ev)496{497	struct ath_hw *ah = sc->sc_ah;498	struct ath_common *common = ath9k_hw_common(ah);499	struct ath_beacon_config *cur_conf;500	struct ath_vif *avp = NULL;501	struct ath_chanctx *ctx;502	u32 tsf_time;503	u32 beacon_int;504 505	if (vif)506		avp = (struct ath_vif *) vif->drv_priv;507 508	spin_lock_bh(&sc->chan_lock);509 510	ath_dbg(common, CHAN_CTX, "cur_chan: %d MHz, event: %s, state: %s, delta: %u ms\n",511		sc->cur_chan->chandef.center_freq1,512		chanctx_event_string(ev),513		chanctx_state_string(sc->sched.state),514		chanctx_event_delta(sc));515 516	switch (ev) {517	case ATH_CHANCTX_EVENT_BEACON_PREPARE:518		if (avp->offchannel_duration)519			avp->offchannel_duration = 0;520 521		if (avp->oneshot_noa) {522			avp->noa_duration = 0;523			avp->oneshot_noa = false;524 525			ath_dbg(common, CHAN_CTX,526				"Clearing oneshot NoA\n");527		}528 529		if (avp->chanctx != sc->cur_chan) {530			ath_dbg(common, CHAN_CTX,531				"Contexts differ, not preparing beacon\n");532			break;533		}534 535		if (sc->sched.offchannel_pending && !sc->sched.wait_switch) {536			sc->sched.offchannel_pending = false;537			sc->next_chan = &sc->offchannel.chan;538			sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON;539			ath_dbg(common, CHAN_CTX,540				"Setting offchannel_pending to false\n");541		}542 543		ctx = ath_chanctx_get_next(sc, sc->cur_chan);544		if (ctx->active && sc->sched.state == ATH_CHANCTX_STATE_IDLE) {545			sc->next_chan = ctx;546			sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON;547			ath_dbg(common, CHAN_CTX,548				"Set next context, move chanctx state to WAIT_FOR_BEACON\n");549		}550 551		/* if the timer missed its window, use the next interval */552		if (sc->sched.state == ATH_CHANCTX_STATE_WAIT_FOR_TIMER) {553			sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON;554			ath_dbg(common, CHAN_CTX,555				"Move chanctx state from WAIT_FOR_TIMER to WAIT_FOR_BEACON\n");556		}557 558		if (sc->sched.mgd_prepare_tx)559			sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON;560 561		/*562		 * When a context becomes inactive, for example,563		 * disassociation of a station context, the NoA564		 * attribute needs to be removed from subsequent565		 * beacons.566		 */567		if (!ctx->active && avp->noa_duration &&568		    sc->sched.state != ATH_CHANCTX_STATE_WAIT_FOR_BEACON) {569			avp->noa_duration = 0;570			avp->periodic_noa = false;571 572			ath_dbg(common, CHAN_CTX,573				"Clearing NoA schedule\n");574		}575 576		if (sc->sched.state != ATH_CHANCTX_STATE_WAIT_FOR_BEACON)577			break;578 579		ath_dbg(common, CHAN_CTX, "Preparing beacon for vif: %pM\n", vif->addr);580 581		sc->sched.beacon_pending = true;582		sc->sched.next_tbtt = REG_READ(ah, AR_NEXT_TBTT_TIMER);583 584		cur_conf = &sc->cur_chan->beacon;585		beacon_int = TU_TO_USEC(cur_conf->beacon_interval);586 587		/* defer channel switch by a quarter beacon interval */588		tsf_time = sc->sched.next_tbtt + beacon_int / 4;589		sc->sched.switch_start_time = tsf_time;590		sc->cur_chan->last_beacon = sc->sched.next_tbtt;591 592		/*593		 * If an offchannel switch is scheduled to happen after594		 * a beacon transmission, update the NoA with one-shot595		 * values and increment the index.596		 */597		if (sc->next_chan == &sc->offchannel.chan) {598			ath_chanctx_offchannel_noa(sc, ctx, avp, tsf_time);599			break;600		}601 602		ath_chanctx_handle_bmiss(sc, ctx, avp);603 604		/*605		 * If a mgd_prepare_tx() has been called by mac80211,606		 * a one-shot NoA needs to be sent. This can happen607		 * with one or more active channel contexts - in both608		 * cases, a new NoA schedule has to be advertised.609		 */610		if (sc->sched.mgd_prepare_tx) {611			ath_chanctx_set_oneshot_noa(sc, avp, tsf_time,612						    jiffies_to_usecs(HZ / 5));613			break;614		}615 616		/* Prevent wrap-around issues */617		if (avp->noa_duration && tsf_time - avp->noa_start > BIT(30))618			avp->noa_duration = 0;619 620		/*621		 * If multiple contexts are active, start periodic622		 * NoA and increment the index for the first623		 * announcement.624		 */625		if (ctx->active &&626		    (!avp->noa_duration || sc->sched.force_noa_update))627			ath_chanctx_set_periodic_noa(sc, avp, cur_conf,628						     tsf_time, beacon_int);629 630		if (ctx->active && sc->sched.force_noa_update)631			sc->sched.force_noa_update = false;632 633		break;634	case ATH_CHANCTX_EVENT_BEACON_SENT:635		if (!sc->sched.beacon_pending) {636			ath_dbg(common, CHAN_CTX,637				"No pending beacon\n");638			break;639		}640 641		sc->sched.beacon_pending = false;642 643		if (sc->sched.mgd_prepare_tx) {644			sc->sched.mgd_prepare_tx = false;645			complete(&sc->go_beacon);646			ath_dbg(common, CHAN_CTX,647				"Beacon sent, complete go_beacon\n");648			break;649		}650 651		if (sc->sched.state != ATH_CHANCTX_STATE_WAIT_FOR_BEACON)652			break;653 654		ath_dbg(common, CHAN_CTX,655			"Move chanctx state to WAIT_FOR_TIMER\n");656 657		sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_TIMER;658		ath_chanctx_setup_timer(sc, sc->sched.switch_start_time);659		break;660	case ATH_CHANCTX_EVENT_TSF_TIMER:661		if (sc->sched.state != ATH_CHANCTX_STATE_WAIT_FOR_TIMER)662			break;663 664		if (!sc->cur_chan->switch_after_beacon &&665		    sc->sched.beacon_pending)666			sc->sched.beacon_miss++;667 668		ath_dbg(common, CHAN_CTX,669			"Move chanctx state to SWITCH\n");670 671		sc->sched.state = ATH_CHANCTX_STATE_SWITCH;672		ieee80211_queue_work(sc->hw, &sc->chanctx_work);673		break;674	case ATH_CHANCTX_EVENT_BEACON_RECEIVED:675		if (!test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags) ||676		    sc->cur_chan == &sc->offchannel.chan)677			break;678 679		sc->sched.beacon_pending = false;680		sc->sched.beacon_miss = 0;681 682		if (sc->sched.state == ATH_CHANCTX_STATE_FORCE_ACTIVE ||683		    !sc->sched.beacon_adjust ||684		    !sc->cur_chan->tsf_val)685			break;686 687		ath_chanctx_adjust_tbtt_delta(sc);688 689		/* TSF time might have been updated by the incoming beacon,690		 * need update the channel switch timer to reflect the change.691		 */692		tsf_time = sc->sched.switch_start_time;693		tsf_time -= (u32) sc->cur_chan->tsf_val +694			ath9k_hw_get_tsf_offset(&sc->cur_chan->tsf_ts, NULL);695		tsf_time += ath9k_hw_gettsf32(ah);696 697		sc->sched.beacon_adjust = false;698		ath_chanctx_setup_timer(sc, tsf_time);699		break;700	case ATH_CHANCTX_EVENT_AUTHORIZED:701		if (sc->sched.state != ATH_CHANCTX_STATE_FORCE_ACTIVE ||702		    avp->chanctx != sc->cur_chan)703			break;704 705		ath_dbg(common, CHAN_CTX,706			"Move chanctx state from FORCE_ACTIVE to IDLE\n");707 708		sc->sched.state = ATH_CHANCTX_STATE_IDLE;709		fallthrough;710	case ATH_CHANCTX_EVENT_SWITCH:711		if (!test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags) ||712		    sc->sched.state == ATH_CHANCTX_STATE_FORCE_ACTIVE ||713		    sc->cur_chan->switch_after_beacon ||714		    sc->cur_chan == &sc->offchannel.chan)715			break;716 717		/* If this is a station chanctx, stay active for a half718		 * beacon period (minus channel switch time)719		 */720		sc->next_chan = ath_chanctx_get_next(sc, sc->cur_chan);721		cur_conf = &sc->cur_chan->beacon;722 723		ath_dbg(common, CHAN_CTX,724			"Move chanctx state to WAIT_FOR_TIMER (event SWITCH)\n");725 726		sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_TIMER;727		sc->sched.wait_switch = false;728 729		tsf_time = TU_TO_USEC(cur_conf->beacon_interval) / 2;730 731		if (sc->sched.extend_absence) {732			sc->sched.beacon_miss = 0;733			tsf_time *= 3;734		}735 736		tsf_time -= sc->sched.channel_switch_time;737		tsf_time += ath9k_hw_gettsf32(sc->sc_ah);738		sc->sched.switch_start_time = tsf_time;739 740		ath_chanctx_setup_timer(sc, tsf_time);741		sc->sched.beacon_pending = true;742		sc->sched.beacon_adjust = true;743		break;744	case ATH_CHANCTX_EVENT_ENABLE_MULTICHANNEL:745		if (sc->cur_chan == &sc->offchannel.chan ||746		    sc->cur_chan->switch_after_beacon)747			break;748 749		sc->next_chan = ath_chanctx_get_next(sc, sc->cur_chan);750		ieee80211_queue_work(sc->hw, &sc->chanctx_work);751		break;752	case ATH_CHANCTX_EVENT_UNASSIGN:753		if (sc->cur_chan->assigned) {754			if (sc->next_chan && !sc->next_chan->assigned &&755			    sc->next_chan != &sc->offchannel.chan)756				sc->sched.state = ATH_CHANCTX_STATE_IDLE;757			break;758		}759 760		ctx = ath_chanctx_get_next(sc, sc->cur_chan);761		sc->sched.state = ATH_CHANCTX_STATE_IDLE;762		if (!ctx->assigned)763			break;764 765		sc->next_chan = ctx;766		ieee80211_queue_work(sc->hw, &sc->chanctx_work);767		break;768	case ATH_CHANCTX_EVENT_ASSIGN:769		break;770	case ATH_CHANCTX_EVENT_CHANGE:771		break;772	}773 774	spin_unlock_bh(&sc->chan_lock);775}776 777void ath_chanctx_beacon_sent_ev(struct ath_softc *sc,778				enum ath_chanctx_event ev)779{780	if (sc->sched.beacon_pending)781		ath_chanctx_event(sc, NULL, ev);782}783 784void ath_chanctx_beacon_recv_ev(struct ath_softc *sc,785				enum ath_chanctx_event ev)786{787	ath_chanctx_event(sc, NULL, ev);788}789 790static int ath_scan_channel_duration(struct ath_softc *sc,791				     struct ieee80211_channel *chan)792{793	struct cfg80211_scan_request *req = sc->offchannel.scan_req;794 795	if (!req->n_ssids || (chan->flags & IEEE80211_CHAN_NO_IR))796		return (HZ / 9); /* ~110 ms */797 798	return (HZ / 16); /* ~60 ms */799}800 801static void ath_chanctx_switch(struct ath_softc *sc, struct ath_chanctx *ctx,802			       struct cfg80211_chan_def *chandef)803{804	struct ath_common *common = ath9k_hw_common(sc->sc_ah);805 806	spin_lock_bh(&sc->chan_lock);807 808	if (test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags) &&809	    (sc->cur_chan != ctx) && (ctx == &sc->offchannel.chan)) {810		if (chandef)811			ctx->chandef = *chandef;812 813		sc->sched.offchannel_pending = true;814		sc->sched.wait_switch = true;815		sc->sched.offchannel_duration =816			jiffies_to_usecs(sc->offchannel.duration) +817			sc->sched.channel_switch_time;818 819		spin_unlock_bh(&sc->chan_lock);820		ath_dbg(common, CHAN_CTX,821			"Set offchannel_pending to true\n");822		return;823	}824 825	sc->next_chan = ctx;826	if (chandef) {827		ctx->chandef = *chandef;828		ath_dbg(common, CHAN_CTX,829			"Assigned next_chan to %d MHz\n", chandef->center_freq1);830	}831 832	if (sc->next_chan == &sc->offchannel.chan) {833		sc->sched.offchannel_duration =834			jiffies_to_usecs(sc->offchannel.duration) +835			sc->sched.channel_switch_time;836 837		if (chandef) {838			ath_dbg(common, CHAN_CTX,839				"Offchannel duration for chan %d MHz : %u\n",840				chandef->center_freq1,841				sc->sched.offchannel_duration);842		}843	}844	spin_unlock_bh(&sc->chan_lock);845	ieee80211_queue_work(sc->hw, &sc->chanctx_work);846}847 848static void ath_chanctx_offchan_switch(struct ath_softc *sc,849				       struct ieee80211_channel *chan)850{851	struct ath_common *common = ath9k_hw_common(sc->sc_ah);852	struct cfg80211_chan_def chandef;853 854	cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);855	ath_dbg(common, CHAN_CTX,856		"Channel definition created: %d MHz\n", chandef.center_freq1);857 858	ath_chanctx_switch(sc, &sc->offchannel.chan, &chandef);859}860 861static struct ath_chanctx *ath_chanctx_get_oper_chan(struct ath_softc *sc,862						     bool active)863{864	struct ath_chanctx *ctx;865 866	ath_for_each_chanctx(sc, ctx) {867		if (!ctx->assigned || list_empty(&ctx->vifs))868			continue;869		if (active && !ctx->active)870			continue;871 872		if (ctx->switch_after_beacon)873			return ctx;874	}875 876	return &sc->chanctx[0];877}878 879static void880ath_scan_next_channel(struct ath_softc *sc)881{882	struct ath_common *common = ath9k_hw_common(sc->sc_ah);883	struct cfg80211_scan_request *req = sc->offchannel.scan_req;884	struct ieee80211_channel *chan;885 886	if (sc->offchannel.scan_idx >= req->n_channels) {887		ath_dbg(common, CHAN_CTX,888			"Moving offchannel state to ATH_OFFCHANNEL_IDLE, "889			"scan_idx: %d, n_channels: %d\n",890			sc->offchannel.scan_idx,891			req->n_channels);892 893		sc->offchannel.state = ATH_OFFCHANNEL_IDLE;894		ath_chanctx_switch(sc, ath_chanctx_get_oper_chan(sc, false),895				   NULL);896		return;897	}898 899	ath_dbg(common, CHAN_CTX,900		"Moving offchannel state to ATH_OFFCHANNEL_PROBE_SEND, scan_idx: %d\n",901		sc->offchannel.scan_idx);902 903	chan = req->channels[sc->offchannel.scan_idx++];904	sc->offchannel.duration = ath_scan_channel_duration(sc, chan);905	sc->offchannel.state = ATH_OFFCHANNEL_PROBE_SEND;906 907	ath_chanctx_offchan_switch(sc, chan);908}909 910void ath_offchannel_next(struct ath_softc *sc)911{912	struct ieee80211_vif *vif;913 914	if (sc->offchannel.scan_req) {915		vif = sc->offchannel.scan_vif;916		sc->offchannel.chan.txpower = vif->bss_conf.txpower;917		ath_scan_next_channel(sc);918	} else if (sc->offchannel.roc_vif) {919		vif = sc->offchannel.roc_vif;920		sc->offchannel.chan.txpower = vif->bss_conf.txpower;921		sc->offchannel.duration =922			msecs_to_jiffies(sc->offchannel.roc_duration);923		sc->offchannel.state = ATH_OFFCHANNEL_ROC_START;924		ath_chanctx_offchan_switch(sc, sc->offchannel.roc_chan);925	} else {926		spin_lock_bh(&sc->chan_lock);927		sc->sched.offchannel_pending = false;928		sc->sched.wait_switch = false;929		spin_unlock_bh(&sc->chan_lock);930 931		ath_chanctx_switch(sc, ath_chanctx_get_oper_chan(sc, false),932				   NULL);933		sc->offchannel.state = ATH_OFFCHANNEL_IDLE;934		if (sc->ps_idle)935			ath_cancel_work(sc);936	}937}938 939void ath_roc_complete(struct ath_softc *sc, enum ath_roc_complete_reason reason)940{941	struct ath_common *common = ath9k_hw_common(sc->sc_ah);942 943	sc->offchannel.roc_vif = NULL;944	sc->offchannel.roc_chan = NULL;945 946	switch (reason) {947	case ATH_ROC_COMPLETE_ABORT:948		ath_dbg(common, CHAN_CTX, "RoC aborted\n");949		ieee80211_remain_on_channel_expired(sc->hw);950		break;951	case ATH_ROC_COMPLETE_EXPIRE:952		ath_dbg(common, CHAN_CTX, "RoC expired\n");953		ieee80211_remain_on_channel_expired(sc->hw);954		break;955	case ATH_ROC_COMPLETE_CANCEL:956		ath_dbg(common, CHAN_CTX, "RoC canceled\n");957		break;958	}959 960	ath_offchannel_next(sc);961	ath9k_ps_restore(sc);962}963 964void ath_scan_complete(struct ath_softc *sc, bool abort)965{966	struct ath_common *common = ath9k_hw_common(sc->sc_ah);967	struct cfg80211_scan_info info = {968		.aborted = abort,969	};970 971	if (abort)972		ath_dbg(common, CHAN_CTX, "HW scan aborted\n");973	else974		ath_dbg(common, CHAN_CTX, "HW scan complete\n");975 976	sc->offchannel.scan_req = NULL;977	sc->offchannel.scan_vif = NULL;978	sc->offchannel.state = ATH_OFFCHANNEL_IDLE;979	ieee80211_scan_completed(sc->hw, &info);980	clear_bit(ATH_OP_SCANNING, &common->op_flags);981	spin_lock_bh(&sc->chan_lock);982	if (test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags))983		sc->sched.force_noa_update = true;984	spin_unlock_bh(&sc->chan_lock);985	ath_offchannel_next(sc);986	ath9k_ps_restore(sc);987}988 989static void ath_scan_send_probe(struct ath_softc *sc,990				struct cfg80211_ssid *ssid)991{992	struct cfg80211_scan_request *req = sc->offchannel.scan_req;993	struct ieee80211_vif *vif = sc->offchannel.scan_vif;994	struct ath_tx_control txctl = {};995	struct sk_buff *skb;996	struct ieee80211_tx_info *info;997	int band = sc->offchannel.chan.chandef.chan->band;998 999	skb = ieee80211_probereq_get(sc->hw, vif->addr,1000			ssid->ssid, ssid->ssid_len, req->ie_len);1001	if (!skb)1002		return;1003 1004	info = IEEE80211_SKB_CB(skb);1005	if (req->no_cck)1006		info->flags |= IEEE80211_TX_CTL_NO_CCK_RATE;1007 1008	if (req->ie_len)1009		skb_put_data(skb, req->ie, req->ie_len);1010 1011	skb_set_queue_mapping(skb, IEEE80211_AC_VO);1012 1013	if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, NULL))1014		goto error;1015 1016	txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];1017	if (ath_tx_start(sc->hw, skb, &txctl))1018		goto error;1019 1020	return;1021 1022error:1023	ieee80211_free_txskb(sc->hw, skb);1024}1025 1026static void ath_scan_channel_start(struct ath_softc *sc)1027{1028	struct ath_common *common = ath9k_hw_common(sc->sc_ah);1029	struct cfg80211_scan_request *req = sc->offchannel.scan_req;1030	int i;1031 1032	if (!(sc->cur_chan->chandef.chan->flags & IEEE80211_CHAN_NO_IR) &&1033	    req->n_ssids) {1034		for (i = 0; i < req->n_ssids; i++)1035			ath_scan_send_probe(sc, &req->ssids[i]);1036 1037	}1038 1039	ath_dbg(common, CHAN_CTX,1040		"Moving offchannel state to ATH_OFFCHANNEL_PROBE_WAIT\n");1041 1042	sc->offchannel.state = ATH_OFFCHANNEL_PROBE_WAIT;1043	mod_timer(&sc->offchannel.timer, jiffies + sc->offchannel.duration);1044}1045 1046static void ath_chanctx_timer(struct timer_list *t)1047{1048	struct ath_softc *sc = from_timer(sc, t, sched.timer);1049	struct ath_common *common = ath9k_hw_common(sc->sc_ah);1050 1051	ath_dbg(common, CHAN_CTX,1052		"Channel context timer invoked\n");1053 1054	ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_TSF_TIMER);1055}1056 1057static void ath_offchannel_timer(struct timer_list *t)1058{1059	struct ath_softc *sc = from_timer(sc, t, offchannel.timer);1060	struct ath_chanctx *ctx;1061	struct ath_common *common = ath9k_hw_common(sc->sc_ah);1062 1063	ath_dbg(common, CHAN_CTX, "%s: offchannel state: %s\n",1064		__func__, offchannel_state_string(sc->offchannel.state));1065 1066	switch (sc->offchannel.state) {1067	case ATH_OFFCHANNEL_PROBE_WAIT:1068		if (!sc->offchannel.scan_req)1069			return;1070 1071		/* get first active channel context */1072		ctx = ath_chanctx_get_oper_chan(sc, true);1073		if (ctx->active) {1074			ath_dbg(common, CHAN_CTX,1075				"Switch to oper/active context, "1076				"move offchannel state to ATH_OFFCHANNEL_SUSPEND\n");1077 1078			sc->offchannel.state = ATH_OFFCHANNEL_SUSPEND;1079			ath_chanctx_switch(sc, ctx, NULL);1080			mod_timer(&sc->offchannel.timer, jiffies + HZ / 10);1081			break;1082		}1083		fallthrough;1084	case ATH_OFFCHANNEL_SUSPEND:1085		if (!sc->offchannel.scan_req)1086			return;1087 1088		ath_scan_next_channel(sc);1089		break;1090	case ATH_OFFCHANNEL_ROC_START:1091	case ATH_OFFCHANNEL_ROC_WAIT:1092		sc->offchannel.state = ATH_OFFCHANNEL_ROC_DONE;1093		ath_roc_complete(sc, ATH_ROC_COMPLETE_EXPIRE);1094		break;1095	default:1096		break;1097	}1098}1099 1100static bool1101ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp,1102			      bool powersave)1103{1104	struct ieee80211_vif *vif = avp->vif;1105	struct ieee80211_sta *sta = NULL;1106	struct ieee80211_hdr_3addr *nullfunc;1107	struct ath_tx_control txctl;1108	struct sk_buff *skb;1109	int band = sc->cur_chan->chandef.chan->band;1110 1111	switch (vif->type) {1112	case NL80211_IFTYPE_STATION:1113		if (!avp->assoc)1114			return false;1115 1116		skb = ieee80211_nullfunc_get(sc->hw, vif, -1, false);1117		if (!skb)1118			return false;1119 1120		nullfunc = (struct ieee80211_hdr_3addr *) skb->data;1121		if (powersave)1122			nullfunc->frame_control |=1123				cpu_to_le16(IEEE80211_FCTL_PM);1124 1125		skb->priority = 7;1126		skb_set_queue_mapping(skb, IEEE80211_AC_VO);1127		if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta)) {1128			dev_kfree_skb_any(skb);1129			return false;1130		}1131		break;1132	default:1133		return false;1134	}1135 1136	memset(&txctl, 0, sizeof(txctl));1137	txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];1138	txctl.sta = sta;1139	if (ath_tx_start(sc->hw, skb, &txctl)) {1140		ieee80211_free_txskb(sc->hw, skb);1141		return false;1142	}1143 1144	return true;1145}1146 1147static bool1148ath_chanctx_send_ps_frame(struct ath_softc *sc, bool powersave)1149{1150	struct ath_vif *avp;1151	bool sent = false;1152 1153	rcu_read_lock();1154	list_for_each_entry(avp, &sc->cur_chan->vifs, list) {1155		if (ath_chanctx_send_vif_ps_frame(sc, avp, powersave))1156			sent = true;1157	}1158	rcu_read_unlock();1159 1160	return sent;1161}1162 1163static bool ath_chanctx_defer_switch(struct ath_softc *sc)1164{1165	struct ath_common *common = ath9k_hw_common(sc->sc_ah);1166 1167	if (sc->cur_chan == &sc->offchannel.chan)1168		return false;1169 1170	switch (sc->sched.state) {1171	case ATH_CHANCTX_STATE_SWITCH:1172		return false;1173	case ATH_CHANCTX_STATE_IDLE:1174		if (!sc->cur_chan->switch_after_beacon)1175			return false;1176 1177		ath_dbg(common, CHAN_CTX,1178			"Defer switch, set chanctx state to WAIT_FOR_BEACON\n");1179 1180		sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON;1181		break;1182	default:1183		break;1184	}1185 1186	return true;1187}1188 1189static void ath_offchannel_channel_change(struct ath_softc *sc)1190{1191	struct ath_common *common = ath9k_hw_common(sc->sc_ah);1192 1193	ath_dbg(common, CHAN_CTX, "%s: offchannel state: %s\n",1194		__func__, offchannel_state_string(sc->offchannel.state));1195 1196	switch (sc->offchannel.state) {1197	case ATH_OFFCHANNEL_PROBE_SEND:1198		if (!sc->offchannel.scan_req)1199			return;1200 1201		if (sc->cur_chan->chandef.chan !=1202		    sc->offchannel.chan.chandef.chan)1203			return;1204 1205		ath_scan_channel_start(sc);1206		break;1207	case ATH_OFFCHANNEL_IDLE:1208		if (!sc->offchannel.scan_req)1209			return;1210 1211		ath_scan_complete(sc, false);1212		break;1213	case ATH_OFFCHANNEL_ROC_START:1214		if (sc->cur_chan != &sc->offchannel.chan)1215			break;1216 1217		sc->offchannel.state = ATH_OFFCHANNEL_ROC_WAIT;1218		mod_timer(&sc->offchannel.timer,1219			  jiffies + sc->offchannel.duration);1220		ieee80211_ready_on_channel(sc->hw);1221		break;1222	case ATH_OFFCHANNEL_ROC_DONE:1223		break;1224	default:1225		break;1226	}1227}1228 1229void ath_chanctx_set_next(struct ath_softc *sc, bool force)1230{1231	struct ath_common *common = ath9k_hw_common(sc->sc_ah);1232	struct ath_chanctx *old_ctx;1233	struct timespec64 ts;1234	bool measure_time = false;1235	bool send_ps = false;1236	bool queues_stopped = false;1237 1238	spin_lock_bh(&sc->chan_lock);1239	if (!sc->next_chan) {1240		spin_unlock_bh(&sc->chan_lock);1241		return;1242	}1243 1244	if (!force && ath_chanctx_defer_switch(sc)) {1245		spin_unlock_bh(&sc->chan_lock);1246		return;1247	}1248 1249	ath_dbg(common, CHAN_CTX,1250		"%s: current: %d MHz, next: %d MHz\n",1251		__func__,1252		sc->cur_chan->chandef.center_freq1,1253		sc->next_chan->chandef.center_freq1);1254 1255	if (sc->cur_chan != sc->next_chan) {1256		ath_dbg(common, CHAN_CTX,1257			"Stopping current chanctx: %d\n",1258			sc->cur_chan->chandef.center_freq1);1259		sc->cur_chan->stopped = true;1260		spin_unlock_bh(&sc->chan_lock);1261 1262		if (sc->next_chan == &sc->offchannel.chan) {1263			ktime_get_raw_ts64(&ts);1264			measure_time = true;1265		}1266 1267		ath9k_chanctx_stop_queues(sc, sc->cur_chan);1268		queues_stopped = true;1269 1270		__ath9k_flush(sc->hw, ~0, true, false, false);1271 1272		if (ath_chanctx_send_ps_frame(sc, true))1273			__ath9k_flush(sc->hw, BIT(IEEE80211_AC_VO),1274				      false, false, false);1275 1276		send_ps = true;1277		spin_lock_bh(&sc->chan_lock);1278 1279		if (sc->cur_chan != &sc->offchannel.chan) {1280			ktime_get_raw_ts64(&sc->cur_chan->tsf_ts);1281			sc->cur_chan->tsf_val = ath9k_hw_gettsf64(sc->sc_ah);1282		}1283	}1284	old_ctx = sc->cur_chan;1285	sc->cur_chan = sc->next_chan;1286	sc->cur_chan->stopped = false;1287	sc->next_chan = NULL;1288 1289	if (!sc->sched.offchannel_pending)1290		sc->sched.offchannel_duration = 0;1291 1292	if (sc->sched.state != ATH_CHANCTX_STATE_FORCE_ACTIVE)1293		sc->sched.state = ATH_CHANCTX_STATE_IDLE;1294 1295	spin_unlock_bh(&sc->chan_lock);1296 1297	if (sc->sc_ah->chip_fullsleep ||1298	    memcmp(&sc->cur_chandef, &sc->cur_chan->chandef,1299		   sizeof(sc->cur_chandef))) {1300		ath_dbg(common, CHAN_CTX,1301			"%s: Set channel %d MHz\n",1302			__func__, sc->cur_chan->chandef.center_freq1);1303		ath_set_channel(sc);1304		if (measure_time)1305			sc->sched.channel_switch_time =1306				ath9k_hw_get_tsf_offset(&ts, NULL);1307		/*1308		 * A reset will ensure that all queues are woken up,1309		 * so there is no need to awaken them again.1310		 */1311		goto out;1312	}1313 1314	if (queues_stopped)1315		ath9k_chanctx_wake_queues(sc, old_ctx);1316out:1317	if (send_ps)1318		ath_chanctx_send_ps_frame(sc, false);1319 1320	ath_offchannel_channel_change(sc);1321	ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_SWITCH);1322}1323 1324static void ath_chanctx_work(struct work_struct *work)1325{1326	struct ath_softc *sc = container_of(work, struct ath_softc,1327					    chanctx_work);1328	mutex_lock(&sc->mutex);1329	ath_chanctx_set_next(sc, false);1330	mutex_unlock(&sc->mutex);1331}1332 1333void ath9k_offchannel_init(struct ath_softc *sc)1334{1335	struct ath_chanctx *ctx;1336	struct ath_common *common = ath9k_hw_common(sc->sc_ah);1337	struct ieee80211_supported_band *sband;1338	struct ieee80211_channel *chan;1339	int i;1340 1341	sband = &common->sbands[NL80211_BAND_2GHZ];1342	if (!sband->n_channels)1343		sband = &common->sbands[NL80211_BAND_5GHZ];1344 1345	chan = &sband->channels[0];1346 1347	ctx = &sc->offchannel.chan;1348	INIT_LIST_HEAD(&ctx->vifs);1349	ctx->txpower = ATH_TXPOWER_MAX;1350	cfg80211_chandef_create(&ctx->chandef, chan, NL80211_CHAN_HT20);1351 1352	for (i = 0; i < ARRAY_SIZE(ctx->acq); i++) {1353		INIT_LIST_HEAD(&ctx->acq[i].acq_new);1354		INIT_LIST_HEAD(&ctx->acq[i].acq_old);1355		spin_lock_init(&ctx->acq[i].lock);1356	}1357 1358	sc->offchannel.chan.offchannel = true;1359}1360 1361void ath9k_init_channel_context(struct ath_softc *sc)1362{1363	INIT_WORK(&sc->chanctx_work, ath_chanctx_work);1364 1365	timer_setup(&sc->offchannel.timer, ath_offchannel_timer, 0);1366	timer_setup(&sc->sched.timer, ath_chanctx_timer, 0);1367 1368	init_completion(&sc->go_beacon);1369}1370 1371void ath9k_deinit_channel_context(struct ath_softc *sc)1372{1373	cancel_work_sync(&sc->chanctx_work);1374}1375 1376bool ath9k_is_chanctx_enabled(void)1377{1378	return (ath9k_use_chanctx == 1);1379}1380 1381/********************/1382/* Queue management */1383/********************/1384 1385void ath9k_chanctx_stop_queues(struct ath_softc *sc, struct ath_chanctx *ctx)1386{1387	struct ath_hw *ah = sc->sc_ah;1388	int i;1389 1390	if (ctx == &sc->offchannel.chan) {1391		ieee80211_stop_queue(sc->hw,1392				     sc->hw->offchannel_tx_hw_queue);1393	} else {1394		for (i = 0; i < IEEE80211_NUM_ACS; i++)1395			ieee80211_stop_queue(sc->hw,1396					     ctx->hw_queue_base + i);1397	}1398 1399	if (ah->opmode == NL80211_IFTYPE_AP)1400		ieee80211_stop_queue(sc->hw, sc->hw->queues - 2);1401}1402 1403 1404void ath9k_chanctx_wake_queues(struct ath_softc *sc, struct ath_chanctx *ctx)1405{1406	struct ath_hw *ah = sc->sc_ah;1407	int i;1408 1409	if (ctx == &sc->offchannel.chan) {1410		ieee80211_wake_queue(sc->hw,1411				     sc->hw->offchannel_tx_hw_queue);1412	} else {1413		for (i = 0; i < IEEE80211_NUM_ACS; i++)1414			ieee80211_wake_queue(sc->hw,1415					     ctx->hw_queue_base + i);1416	}1417 1418	if (ah->opmode == NL80211_IFTYPE_AP)1419		ieee80211_wake_queue(sc->hw, sc->hw->queues - 2);1420}1421 1422/*****************/1423/* P2P Powersave */1424/*****************/1425 1426static void ath9k_update_p2p_ps_timer(struct ath_softc *sc, struct ath_vif *avp)1427{1428	struct ath_common *common = ath9k_hw_common(sc->sc_ah);1429	struct ath_hw *ah = sc->sc_ah;1430	u32 tsf, target_tsf;1431 1432	if (!avp || !avp->noa.has_next_tsf)1433		return;1434 1435	ath9k_hw_gen_timer_stop(ah, sc->p2p_ps_timer);1436 1437	tsf = ath9k_hw_gettsf32(sc->sc_ah);1438 1439	target_tsf = avp->noa.next_tsf;1440	if (!avp->noa.absent)1441		target_tsf -= ATH_P2P_PS_STOP_TIME;1442	else1443		target_tsf += ATH_P2P_PS_STOP_TIME;1444 1445	if (target_tsf - tsf < ATH_P2P_PS_STOP_TIME)1446		target_tsf = tsf + ATH_P2P_PS_STOP_TIME;1447 1448	ath_dbg(common, CHAN_CTX, "%s absent %d tsf 0x%08X next_tsf 0x%08X (%dms)\n",1449		__func__, avp->noa.absent, tsf, target_tsf,1450		(target_tsf - tsf) / 1000);1451 1452	ath9k_hw_gen_timer_start(ah, sc->p2p_ps_timer, target_tsf, 1000000);1453}1454 1455static void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif)1456{1457	struct ath_vif *avp = (void *)vif->drv_priv;1458	u32 tsf;1459 1460	if (!sc->p2p_ps_timer)1461		return;1462 1463	if (vif->type != NL80211_IFTYPE_STATION)1464		return;1465 1466	sc->p2p_ps_vif = avp;1467 1468	if (sc->ps_flags & PS_BEACON_SYNC)1469		return;1470 1471	tsf = ath9k_hw_gettsf32(sc->sc_ah);1472	ieee80211_parse_p2p_noa(&vif->bss_conf.p2p_noa_attr, &avp->noa, tsf);1473	ath9k_update_p2p_ps_timer(sc, avp);1474}1475 1476static u8 ath9k_get_ctwin(struct ath_softc *sc, struct ath_vif *avp)1477{1478	struct ath_beacon_config *cur_conf = &sc->cur_chan->beacon;1479	u8 switch_time, ctwin;1480 1481	/*1482	 * Channel switch in multi-channel mode is deferred1483	 * by a quarter beacon interval when handling1484	 * ATH_CHANCTX_EVENT_BEACON_PREPARE, so the P2P-GO1485	 * interface is guaranteed to be discoverable1486	 * for that duration after a TBTT.1487	 */1488	switch_time = cur_conf->beacon_interval / 4;1489 1490	ctwin = avp->vif->bss_conf.p2p_noa_attr.oppps_ctwindow;1491	if (ctwin && (ctwin < switch_time))1492		return ctwin;1493 1494	if (switch_time < P2P_DEFAULT_CTWIN)1495		return 0;1496 1497	return P2P_DEFAULT_CTWIN;1498}1499 1500void ath9k_beacon_add_noa(struct ath_softc *sc, struct ath_vif *avp,1501			  struct sk_buff *skb)1502{1503	static const u8 noa_ie_hdr[] = {1504		WLAN_EID_VENDOR_SPECIFIC,	/* type */1505		0,				/* length */1506		0x50, 0x6f, 0x9a,		/* WFA OUI */1507		0x09,				/* P2P subtype */1508		0x0c,				/* Notice of Absence */1509		0x00,				/* LSB of little-endian len */1510		0x00,				/* MSB of little-endian len */1511	};1512 1513	struct ieee80211_p2p_noa_attr *noa;1514	int noa_len, noa_desc, i = 0;1515	u8 *hdr;1516 1517	if (!avp->offchannel_duration && !avp->noa_duration)1518		return;1519 1520	noa_desc = !!avp->offchannel_duration + !!avp->noa_duration;1521	noa_len = 2 + sizeof(struct ieee80211_p2p_noa_desc) * noa_desc;1522 1523	hdr = skb_put_data(skb, noa_ie_hdr, sizeof(noa_ie_hdr));1524	hdr[1] = sizeof(noa_ie_hdr) + noa_len - 2;1525	hdr[7] = noa_len;1526 1527	noa = skb_put_zero(skb, noa_len);1528 1529	noa->index = avp->noa_index;1530	noa->oppps_ctwindow = ath9k_get_ctwin(sc, avp);1531	if (noa->oppps_ctwindow)1532		noa->oppps_ctwindow |= BIT(7);1533 1534	if (avp->noa_duration) {1535		if (avp->periodic_noa) {1536			u32 interval = TU_TO_USEC(sc->cur_chan->beacon.beacon_interval);1537			noa->desc[i].count = 255;1538			noa->desc[i].interval = cpu_to_le32(interval);1539		} else {1540			noa->desc[i].count = 1;1541		}1542 1543		noa->desc[i].start_time = cpu_to_le32(avp->noa_start);1544		noa->desc[i].duration = cpu_to_le32(avp->noa_duration);1545		i++;1546	}1547 1548	if (avp->offchannel_duration) {1549		noa->desc[i].count = 1;1550		noa->desc[i].start_time = cpu_to_le32(avp->offchannel_start);1551		noa->desc[i].duration = cpu_to_le32(avp->offchannel_duration);1552	}1553}1554 1555void ath9k_p2p_ps_timer(void *priv)1556{1557	struct ath_softc *sc = priv;1558	struct ath_vif *avp = sc->p2p_ps_vif;1559	struct ieee80211_vif *vif;1560	struct ieee80211_sta *sta;1561	struct ath_node *an;1562	u32 tsf;1563 1564	del_timer_sync(&sc->sched.timer);1565	ath9k_hw_gen_timer_stop(sc->sc_ah, sc->p2p_ps_timer);1566	ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_TSF_TIMER);1567 1568	if (!avp || avp->chanctx != sc->cur_chan)1569		return;1570 1571	tsf = ath9k_hw_gettsf32(sc->sc_ah);1572	if (!avp->noa.absent)1573		tsf += ATH_P2P_PS_STOP_TIME;1574	else1575		tsf -= ATH_P2P_PS_STOP_TIME;1576 1577	if (!avp->noa.has_next_tsf ||1578	    avp->noa.next_tsf - tsf > BIT(31))1579		ieee80211_update_p2p_noa(&avp->noa, tsf);1580 1581	ath9k_update_p2p_ps_timer(sc, avp);1582 1583	rcu_read_lock();1584 1585	vif = avp->vif;1586	sta = ieee80211_find_sta(vif, avp->bssid);1587	if (!sta)1588		goto out;1589 1590	an = (void *) sta->drv_priv;1591	if (an->sleeping == !!avp->noa.absent)1592		goto out;1593 1594	an->sleeping = avp->noa.absent;1595	if (an->sleeping)1596		ath_tx_aggr_sleep(sta, sc, an);1597	else1598		ath_tx_aggr_wakeup(sc, an);1599 1600out:1601	rcu_read_unlock();1602}1603 1604void ath9k_p2p_bss_info_changed(struct ath_softc *sc,1605				struct ieee80211_vif *vif)1606{1607	unsigned long flags;1608 1609	spin_lock_bh(&sc->sc_pcu_lock);1610	spin_lock_irqsave(&sc->sc_pm_lock, flags);1611	ath9k_update_p2p_ps(sc, vif);1612	spin_unlock_irqrestore(&sc->sc_pm_lock, flags);1613	spin_unlock_bh(&sc->sc_pcu_lock);1614}1615 1616void ath9k_p2p_beacon_sync(struct ath_softc *sc)1617{1618	if (sc->p2p_ps_vif)1619		ath9k_update_p2p_ps(sc, sc->p2p_ps_vif->vif);1620}1621 1622void ath9k_p2p_remove_vif(struct ath_softc *sc,1623			  struct ieee80211_vif *vif)1624{1625	struct ath_vif *avp = (void *)vif->drv_priv;1626 1627	spin_lock_bh(&sc->sc_pcu_lock);1628	if (avp == sc->p2p_ps_vif) {1629		sc->p2p_ps_vif = NULL;1630		ath9k_update_p2p_ps_timer(sc, NULL);1631	}1632	spin_unlock_bh(&sc->sc_pcu_lock);1633}1634 1635int ath9k_init_p2p(struct ath_softc *sc)1636{1637	sc->p2p_ps_timer = ath_gen_timer_alloc(sc->sc_ah, ath9k_p2p_ps_timer,1638					       NULL, sc, AR_FIRST_NDP_TIMER);1639	if (!sc->p2p_ps_timer)1640		return -ENOMEM;1641 1642	return 0;1643}1644 1645void ath9k_deinit_p2p(struct ath_softc *sc)1646{1647	if (sc->p2p_ps_timer)1648		ath_gen_timer_free(sc->sc_ah, sc->p2p_ps_timer);1649}1650 1651#endif /* CONFIG_ATH9K_CHANNEL_CONTEXT */1652