1 /*
2  * Copyright (c) 2010 Atheros Communications 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 "htc.h"
18 
19 #define FUDGE 2
20 
21 static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
22 					struct htc_beacon_config *bss_conf)
23 {
24 	struct ath_common *common = ath9k_hw_common(priv->ah);
25 	struct ath9k_beacon_state bs;
26 	enum ath9k_int imask = 0;
27 	int dtimperiod, dtimcount, sleepduration;
28 	int cfpperiod, cfpcount, bmiss_timeout;
29 	u32 nexttbtt = 0, intval, tsftu;
30 	__be32 htc_imask = 0;
31 	u64 tsf;
32 	int num_beacons, offset, dtim_dec_count, cfp_dec_count;
33 	int ret;
34 	u8 cmd_rsp;
35 
36 	memset(&bs, 0, sizeof(bs));
37 
38 	intval = bss_conf->beacon_interval & ATH9K_BEACON_PERIOD;
39 	bmiss_timeout = (ATH_DEFAULT_BMISS_LIMIT * bss_conf->beacon_interval);
40 
41 	/*
42 	 * Setup dtim and cfp parameters according to
43 	 * last beacon we received (which may be none).
44 	 */
45 	dtimperiod = bss_conf->dtim_period;
46 	if (dtimperiod <= 0)		/* NB: 0 if not known */
47 		dtimperiod = 1;
48 	dtimcount = 1;
49 	if (dtimcount >= dtimperiod)	/* NB: sanity check */
50 		dtimcount = 0;
51 	cfpperiod = 1;			/* NB: no PCF support yet */
52 	cfpcount = 0;
53 
54 	sleepduration = intval;
55 	if (sleepduration <= 0)
56 		sleepduration = intval;
57 
58 	/*
59 	 * Pull nexttbtt forward to reflect the current
60 	 * TSF and calculate dtim+cfp state for the result.
61 	 */
62 	tsf = ath9k_hw_gettsf64(priv->ah);
63 	tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
64 
65 	num_beacons = tsftu / intval + 1;
66 	offset = tsftu % intval;
67 	nexttbtt = tsftu - offset;
68 	if (offset)
69 		nexttbtt += intval;
70 
71 	/* DTIM Beacon every dtimperiod Beacon */
72 	dtim_dec_count = num_beacons % dtimperiod;
73 	/* CFP every cfpperiod DTIM Beacon */
74 	cfp_dec_count = (num_beacons / dtimperiod) % cfpperiod;
75 	if (dtim_dec_count)
76 		cfp_dec_count++;
77 
78 	dtimcount -= dtim_dec_count;
79 	if (dtimcount < 0)
80 		dtimcount += dtimperiod;
81 
82 	cfpcount -= cfp_dec_count;
83 	if (cfpcount < 0)
84 		cfpcount += cfpperiod;
85 
86 	bs.bs_intval = intval;
87 	bs.bs_nexttbtt = nexttbtt;
88 	bs.bs_dtimperiod = dtimperiod*intval;
89 	bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount*intval;
90 	bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod;
91 	bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod;
92 	bs.bs_cfpmaxduration = 0;
93 
94 	/*
95 	 * Calculate the number of consecutive beacons to miss* before taking
96 	 * a BMISS interrupt. The configuration is specified in TU so we only
97 	 * need calculate based	on the beacon interval.  Note that we clamp the
98 	 * result to at most 15 beacons.
99 	 */
100 	if (sleepduration > intval) {
101 		bs.bs_bmissthreshold = ATH_DEFAULT_BMISS_LIMIT / 2;
102 	} else {
103 		bs.bs_bmissthreshold = DIV_ROUND_UP(bmiss_timeout, intval);
104 		if (bs.bs_bmissthreshold > 15)
105 			bs.bs_bmissthreshold = 15;
106 		else if (bs.bs_bmissthreshold <= 0)
107 			bs.bs_bmissthreshold = 1;
108 	}
109 
110 	/*
111 	 * Calculate sleep duration. The configuration is given in ms.
112 	 * We ensure a multiple of the beacon period is used. Also, if the sleep
113 	 * duration is greater than the DTIM period then it makes senses
114 	 * to make it a multiple of that.
115 	 *
116 	 * XXX fixed at 100ms
117 	 */
118 
119 	bs.bs_sleepduration = roundup(IEEE80211_MS_TO_TU(100), sleepduration);
120 	if (bs.bs_sleepduration > bs.bs_dtimperiod)
121 		bs.bs_sleepduration = bs.bs_dtimperiod;
122 
123 	/* TSF out of range threshold fixed at 1 second */
124 	bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD;
125 
126 	ath_dbg(common, ATH_DBG_CONFIG, "intval: %u tsf: %llu tsftu: %u\n",
127 		intval, tsf, tsftu);
128 	ath_dbg(common, ATH_DBG_CONFIG,
129 		"bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
130 		bs.bs_bmissthreshold, bs.bs_sleepduration,
131 		bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
132 
133 	/* Set the computed STA beacon timers */
134 
135 	WMI_CMD(WMI_DISABLE_INTR_CMDID);
136 	ath9k_hw_set_sta_beacon_timers(priv->ah, &bs);
137 	imask |= ATH9K_INT_BMISS;
138 	htc_imask = cpu_to_be32(imask);
139 	WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask);
140 }
141 
142 static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv,
143 				       struct htc_beacon_config *bss_conf)
144 {
145 	struct ath_common *common = ath9k_hw_common(priv->ah);
146 	enum ath9k_int imask = 0;
147 	u32 nexttbtt, intval, tsftu;
148 	__be32 htc_imask = 0;
149 	int ret;
150 	u8 cmd_rsp;
151 	u64 tsf;
152 
153 	intval = bss_conf->beacon_interval & ATH9K_BEACON_PERIOD;
154 	intval /= ATH9K_HTC_MAX_BCN_VIF;
155 	nexttbtt = intval;
156 
157 	if (priv->op_flags & OP_TSF_RESET) {
158 		intval |= ATH9K_BEACON_RESET_TSF;
159 		priv->op_flags &= ~OP_TSF_RESET;
160 	} else {
161 		/*
162 		 * Pull nexttbtt forward to reflect the current TSF.
163 		 */
164 		tsf = ath9k_hw_gettsf64(priv->ah);
165 		tsftu = TSF_TO_TU(tsf >> 32, tsf) + FUDGE;
166 		do {
167 			nexttbtt += intval;
168 		} while (nexttbtt < tsftu);
169 	}
170 
171 	intval |= ATH9K_BEACON_ENA;
172 
173 	if (priv->op_flags & OP_ENABLE_BEACON)
174 		imask |= ATH9K_INT_SWBA;
175 
176 	ath_dbg(common, ATH_DBG_CONFIG,
177 		"AP Beacon config, intval: %d, nexttbtt: %u imask: 0x%x\n",
178 		bss_conf->beacon_interval, nexttbtt, imask);
179 
180 	WMI_CMD(WMI_DISABLE_INTR_CMDID);
181 	ath9k_hw_beaconinit(priv->ah, nexttbtt, intval);
182 	priv->bmiss_cnt = 0;
183 	htc_imask = cpu_to_be32(imask);
184 	WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask);
185 }
186 
187 static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv,
188 					  struct htc_beacon_config *bss_conf)
189 {
190 	struct ath_common *common = ath9k_hw_common(priv->ah);
191 	enum ath9k_int imask = 0;
192 	u32 nexttbtt, intval, tsftu;
193 	__be32 htc_imask = 0;
194 	int ret;
195 	u8 cmd_rsp;
196 	u64 tsf;
197 
198 	intval = bss_conf->beacon_interval & ATH9K_BEACON_PERIOD;
199 	nexttbtt = intval;
200 
201 	/*
202 	 * Pull nexttbtt forward to reflect the current TSF.
203 	 */
204 	tsf = ath9k_hw_gettsf64(priv->ah);
205 	tsftu = TSF_TO_TU(tsf >> 32, tsf) + FUDGE;
206 	do {
207 		nexttbtt += intval;
208 	} while (nexttbtt < tsftu);
209 
210 	intval |= ATH9K_BEACON_ENA;
211 	if (priv->op_flags & OP_ENABLE_BEACON)
212 		imask |= ATH9K_INT_SWBA;
213 
214 	ath_dbg(common, ATH_DBG_CONFIG,
215 		"IBSS Beacon config, intval: %d, nexttbtt: %u, imask: 0x%x\n",
216 		bss_conf->beacon_interval, nexttbtt, imask);
217 
218 	WMI_CMD(WMI_DISABLE_INTR_CMDID);
219 	ath9k_hw_beaconinit(priv->ah, nexttbtt, intval);
220 	priv->bmiss_cnt = 0;
221 	htc_imask = cpu_to_be32(imask);
222 	WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask);
223 }
224 
225 void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb,
226 			enum htc_endpoint_id ep_id, bool txok)
227 {
228 	dev_kfree_skb_any(skb);
229 }
230 
231 void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending)
232 {
233 	struct ath9k_htc_vif *avp = (void *)priv->vif->drv_priv;
234 	struct tx_beacon_header beacon_hdr;
235 	struct ath9k_htc_tx_ctl tx_ctl;
236 	struct ieee80211_tx_info *info;
237 	struct sk_buff *beacon;
238 	u8 *tx_fhdr;
239 
240 	memset(&beacon_hdr, 0, sizeof(struct tx_beacon_header));
241 	memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl));
242 
243 	/* FIXME: Handle BMISS */
244 	if (beacon_pending != 0) {
245 		priv->bmiss_cnt++;
246 		return;
247 	}
248 
249 	spin_lock_bh(&priv->beacon_lock);
250 
251 	if (unlikely(priv->op_flags & OP_SCANNING)) {
252 		spin_unlock_bh(&priv->beacon_lock);
253 		return;
254 	}
255 
256 	/* Get a new beacon */
257 	beacon = ieee80211_beacon_get(priv->hw, priv->vif);
258 	if (!beacon) {
259 		spin_unlock_bh(&priv->beacon_lock);
260 		return;
261 	}
262 
263 	info = IEEE80211_SKB_CB(beacon);
264 	if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
265 		struct ieee80211_hdr *hdr =
266 			(struct ieee80211_hdr *) beacon->data;
267 		avp->seq_no += 0x10;
268 		hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
269 		hdr->seq_ctrl |= cpu_to_le16(avp->seq_no);
270 	}
271 
272 	tx_ctl.type = ATH9K_HTC_NORMAL;
273 	beacon_hdr.vif_index = avp->index;
274 	tx_fhdr = skb_push(beacon, sizeof(beacon_hdr));
275 	memcpy(tx_fhdr, (u8 *) &beacon_hdr, sizeof(beacon_hdr));
276 
277 	htc_send(priv->htc, beacon, priv->beacon_ep, &tx_ctl);
278 
279 	spin_unlock_bh(&priv->beacon_lock);
280 }
281 
282 /* Currently, only for IBSS */
283 void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv)
284 {
285 	struct ath_hw *ah = priv->ah;
286 	struct ath9k_tx_queue_info qi, qi_be;
287 	int qnum = priv->hwq_map[WME_AC_BE];
288 
289 	memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
290 	memset(&qi_be, 0, sizeof(struct ath9k_tx_queue_info));
291 
292 	ath9k_hw_get_txq_props(ah, qnum, &qi_be);
293 
294 	qi.tqi_aifs = qi_be.tqi_aifs;
295 	/* For WIFI Beacon Distribution
296 	 * Long slot time  : 2x cwmin
297 	 * Short slot time : 4x cwmin
298 	 */
299 	if (ah->slottime == ATH9K_SLOT_TIME_20)
300 		qi.tqi_cwmin = 2*qi_be.tqi_cwmin;
301 	else
302 		qi.tqi_cwmin = 4*qi_be.tqi_cwmin;
303 	qi.tqi_cwmax = qi_be.tqi_cwmax;
304 
305 	if (!ath9k_hw_set_txq_props(ah, priv->beaconq, &qi)) {
306 		ath_err(ath9k_hw_common(ah),
307 			"Unable to update beacon queue %u!\n", qnum);
308 	} else {
309 		ath9k_hw_resettxqueue(ah, priv->beaconq);
310 	}
311 }
312 
313 static void ath9k_htc_beacon_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
314 {
315 	bool *beacon_configured = (bool *)data;
316 	struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;
317 
318 	if (vif->type == NL80211_IFTYPE_STATION &&
319 	    avp->beacon_configured)
320 		*beacon_configured = true;
321 }
322 
323 static bool ath9k_htc_check_beacon_config(struct ath9k_htc_priv *priv,
324 					  struct ieee80211_vif *vif)
325 {
326 	struct ath_common *common = ath9k_hw_common(priv->ah);
327 	struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf;
328 	struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
329 	bool beacon_configured;
330 
331 	/*
332 	 * Changing the beacon interval when multiple AP interfaces
333 	 * are configured will affect beacon transmission of all
334 	 * of them.
335 	 */
336 	if ((priv->ah->opmode == NL80211_IFTYPE_AP) &&
337 	    (priv->num_ap_vif > 1) &&
338 	    (vif->type == NL80211_IFTYPE_AP) &&
339 	    (cur_conf->beacon_interval != bss_conf->beacon_int)) {
340 		ath_dbg(common, ATH_DBG_CONFIG,
341 			"Changing beacon interval of multiple AP interfaces !\n");
342 		return false;
343 	}
344 
345 	/*
346 	 * If the HW is operating in AP mode, any new station interfaces that
347 	 * are added cannot change the beacon parameters.
348 	 */
349 	if (priv->num_ap_vif &&
350 	    (vif->type != NL80211_IFTYPE_AP)) {
351 		ath_dbg(common, ATH_DBG_CONFIG,
352 			"HW in AP mode, cannot set STA beacon parameters\n");
353 		return false;
354 	}
355 
356 	/*
357 	 * The beacon parameters are configured only for the first
358 	 * station interface.
359 	 */
360 	if ((priv->ah->opmode == NL80211_IFTYPE_STATION) &&
361 	    (priv->num_sta_vif > 1) &&
362 	    (vif->type == NL80211_IFTYPE_STATION)) {
363 		beacon_configured = false;
364 		ieee80211_iterate_active_interfaces_atomic(priv->hw,
365 							   ath9k_htc_beacon_iter,
366 							   &beacon_configured);
367 
368 		if (beacon_configured) {
369 			ath_dbg(common, ATH_DBG_CONFIG,
370 				"Beacon already configured for a station interface\n");
371 			return false;
372 		}
373 	}
374 
375 	return true;
376 }
377 
378 void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
379 			     struct ieee80211_vif *vif)
380 {
381 	struct ath_common *common = ath9k_hw_common(priv->ah);
382 	struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf;
383 	struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
384 	struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;
385 
386 	if (!ath9k_htc_check_beacon_config(priv, vif))
387 		return;
388 
389 	cur_conf->beacon_interval = bss_conf->beacon_int;
390 	if (cur_conf->beacon_interval == 0)
391 		cur_conf->beacon_interval = 100;
392 
393 	cur_conf->dtim_period = bss_conf->dtim_period;
394 	cur_conf->bmiss_timeout =
395 		ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval;
396 
397 	switch (vif->type) {
398 	case NL80211_IFTYPE_STATION:
399 		ath9k_htc_beacon_config_sta(priv, cur_conf);
400 		avp->beacon_configured = true;
401 		break;
402 	case NL80211_IFTYPE_ADHOC:
403 		ath9k_htc_beacon_config_adhoc(priv, cur_conf);
404 		break;
405 	case NL80211_IFTYPE_AP:
406 		ath9k_htc_beacon_config_ap(priv, cur_conf);
407 		break;
408 	default:
409 		ath_dbg(common, ATH_DBG_CONFIG,
410 			"Unsupported beaconing mode\n");
411 		return;
412 	}
413 }
414 
415 void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv)
416 {
417 	struct ath_common *common = ath9k_hw_common(priv->ah);
418 	struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf;
419 
420 	switch (priv->ah->opmode) {
421 	case NL80211_IFTYPE_STATION:
422 		ath9k_htc_beacon_config_sta(priv, cur_conf);
423 		break;
424 	case NL80211_IFTYPE_ADHOC:
425 		ath9k_htc_beacon_config_adhoc(priv, cur_conf);
426 		break;
427 	case NL80211_IFTYPE_AP:
428 		ath9k_htc_beacon_config_ap(priv, cur_conf);
429 		break;
430 	default:
431 		ath_dbg(common, ATH_DBG_CONFIG,
432 			"Unsupported beaconing mode\n");
433 		return;
434 	}
435 }
436