beacon.c revision 130ef6e9dc76f821caf98fa9ed6e2dafe15f3b1f
1/* 2 * Copyright (c) 2008-2011 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 <linux/dma-mapping.h> 18#include "ath9k.h" 19 20#define FUDGE 2 21 22static void ath9k_reset_beacon_status(struct ath_softc *sc) 23{ 24 sc->beacon.tx_processed = false; 25 sc->beacon.tx_last = false; 26} 27 28/* 29 * This function will modify certain transmit queue properties depending on 30 * the operating mode of the station (AP or AdHoc). Parameters are AIFS 31 * settings and channel width min/max 32*/ 33int ath_beaconq_config(struct ath_softc *sc) 34{ 35 struct ath_hw *ah = sc->sc_ah; 36 struct ath_common *common = ath9k_hw_common(ah); 37 struct ath9k_tx_queue_info qi, qi_be; 38 struct ath_txq *txq; 39 40 ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi); 41 if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) { 42 /* Always burst out beacon and CAB traffic. */ 43 qi.tqi_aifs = 1; 44 qi.tqi_cwmin = 0; 45 qi.tqi_cwmax = 0; 46 } else { 47 /* Adhoc mode; important thing is to use 2x cwmin. */ 48 txq = sc->tx.txq_map[WME_AC_BE]; 49 ath9k_hw_get_txq_props(ah, txq->axq_qnum, &qi_be); 50 qi.tqi_aifs = qi_be.tqi_aifs; 51 if (ah->slottime == ATH9K_SLOT_TIME_20) 52 qi.tqi_cwmin = 2*qi_be.tqi_cwmin; 53 else 54 qi.tqi_cwmin = 4*qi_be.tqi_cwmin; 55 qi.tqi_cwmax = qi_be.tqi_cwmax; 56 } 57 58 if (!ath9k_hw_set_txq_props(ah, sc->beacon.beaconq, &qi)) { 59 ath_err(common, 60 "Unable to update h/w beacon queue parameters\n"); 61 return 0; 62 } else { 63 ath9k_hw_resettxqueue(ah, sc->beacon.beaconq); 64 return 1; 65 } 66} 67 68/* 69 * Associates the beacon frame buffer with a transmit descriptor. Will set 70 * up rate codes, and channel flags. Beacons are always sent out at the 71 * lowest rate, and are not retried. 72*/ 73static void ath_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif, 74 struct ath_buf *bf, int rateidx) 75{ 76 struct sk_buff *skb = bf->bf_mpdu; 77 struct ath_hw *ah = sc->sc_ah; 78 struct ath_common *common = ath9k_hw_common(ah); 79 struct ath_tx_info info; 80 struct ieee80211_supported_band *sband; 81 u8 chainmask = ah->txchainmask; 82 u8 rate = 0; 83 84 ath9k_reset_beacon_status(sc); 85 86 sband = &sc->sbands[common->hw->conf.channel->band]; 87 rate = sband->bitrates[rateidx].hw_value; 88 if (vif->bss_conf.use_short_preamble) 89 rate |= sband->bitrates[rateidx].hw_value_short; 90 91 memset(&info, 0, sizeof(info)); 92 info.pkt_len = skb->len + FCS_LEN; 93 info.type = ATH9K_PKT_TYPE_BEACON; 94 info.txpower = MAX_RATE_POWER; 95 info.keyix = ATH9K_TXKEYIX_INVALID; 96 info.keytype = ATH9K_KEY_TYPE_CLEAR; 97 info.flags = ATH9K_TXDESC_NOACK | ATH9K_TXDESC_CLRDMASK; 98 99 info.buf_addr[0] = bf->bf_buf_addr; 100 info.buf_len[0] = roundup(skb->len, 4); 101 102 info.is_first = true; 103 info.is_last = true; 104 105 info.qcu = sc->beacon.beaconq; 106 107 info.rates[0].Tries = 1; 108 info.rates[0].Rate = rate; 109 info.rates[0].ChSel = ath_txchainmask_reduction(sc, chainmask, rate); 110 111 ath9k_hw_set_txdesc(ah, bf->bf_desc, &info); 112} 113 114static void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) 115{ 116 struct ath_softc *sc = hw->priv; 117 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 118 struct ath_tx_control txctl; 119 120 memset(&txctl, 0, sizeof(struct ath_tx_control)); 121 txctl.txq = sc->beacon.cabq; 122 123 ath_dbg(common, XMIT, "transmitting CABQ packet, skb: %p\n", skb); 124 125 if (ath_tx_start(hw, skb, &txctl) != 0) { 126 ath_dbg(common, XMIT, "CABQ TX failed\n"); 127 dev_kfree_skb_any(skb); 128 } 129} 130 131static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, 132 struct ieee80211_vif *vif) 133{ 134 struct ath_softc *sc = hw->priv; 135 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 136 struct ath_buf *bf; 137 struct ath_vif *avp; 138 struct sk_buff *skb; 139 struct ath_txq *cabq; 140 struct ieee80211_tx_info *info; 141 int cabq_depth; 142 143 ath9k_reset_beacon_status(sc); 144 145 avp = (void *)vif->drv_priv; 146 cabq = sc->beacon.cabq; 147 148 if ((avp->av_bcbuf == NULL) || !avp->is_bslot_active) 149 return NULL; 150 151 /* Release the old beacon first */ 152 153 bf = avp->av_bcbuf; 154 skb = bf->bf_mpdu; 155 if (skb) { 156 dma_unmap_single(sc->dev, bf->bf_buf_addr, 157 skb->len, DMA_TO_DEVICE); 158 dev_kfree_skb_any(skb); 159 bf->bf_buf_addr = 0; 160 } 161 162 /* Get a new beacon from mac80211 */ 163 164 skb = ieee80211_beacon_get(hw, vif); 165 bf->bf_mpdu = skb; 166 if (skb == NULL) 167 return NULL; 168 ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp = 169 avp->tsf_adjust; 170 171 info = IEEE80211_SKB_CB(skb); 172 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { 173 /* 174 * TODO: make sure the seq# gets assigned properly (vs. other 175 * TX frames) 176 */ 177 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 178 sc->tx.seq_no += 0x10; 179 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); 180 hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no); 181 } 182 183 bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, 184 skb->len, DMA_TO_DEVICE); 185 if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) { 186 dev_kfree_skb_any(skb); 187 bf->bf_mpdu = NULL; 188 bf->bf_buf_addr = 0; 189 ath_err(common, "dma_mapping_error on beaconing\n"); 190 return NULL; 191 } 192 193 skb = ieee80211_get_buffered_bc(hw, vif); 194 195 /* 196 * if the CABQ traffic from previous DTIM is pending and the current 197 * beacon is also a DTIM. 198 * 1) if there is only one vif let the cab traffic continue. 199 * 2) if there are more than one vif and we are using staggered 200 * beacons, then drain the cabq by dropping all the frames in 201 * the cabq so that the current vifs cab traffic can be scheduled. 202 */ 203 spin_lock_bh(&cabq->axq_lock); 204 cabq_depth = cabq->axq_depth; 205 spin_unlock_bh(&cabq->axq_lock); 206 207 if (skb && cabq_depth) { 208 if (sc->nvifs > 1) { 209 ath_dbg(common, BEACON, 210 "Flushing previous cabq traffic\n"); 211 ath_draintxq(sc, cabq, false); 212 } 213 } 214 215 ath_beacon_setup(sc, vif, bf, info->control.rates[0].idx); 216 217 while (skb) { 218 ath_tx_cabq(hw, skb); 219 skb = ieee80211_get_buffered_bc(hw, vif); 220 } 221 222 return bf; 223} 224 225void ath9k_beacon_assign_slot(struct ath_softc *sc, struct ieee80211_vif *vif) 226{ 227 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 228 struct ath_vif *avp = (void *)vif->drv_priv; 229 int slot; 230 231 avp->av_bcbuf = list_first_entry(&sc->beacon.bbuf, struct ath_buf, list); 232 list_del(&avp->av_bcbuf->list); 233 234 for (slot = 0; slot < ATH_BCBUF; slot++) { 235 if (sc->beacon.bslot[slot] == NULL) { 236 avp->av_bslot = slot; 237 avp->is_bslot_active = false; 238 break; 239 } 240 } 241 242 sc->beacon.bslot[avp->av_bslot] = vif; 243 sc->nbcnvifs++; 244 245 ath_dbg(common, CONFIG, "Added interface at beacon slot: %d\n", 246 avp->av_bslot); 247} 248 249void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif) 250{ 251 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 252 struct ath_vif *avp = (void *)vif->drv_priv; 253 struct ath_buf *bf = avp->av_bcbuf; 254 255 ath_dbg(common, CONFIG, "Removing interface at beacon slot: %d\n", 256 avp->av_bslot); 257 258 tasklet_disable(&sc->bcon_tasklet); 259 260 if (bf && bf->bf_mpdu) { 261 struct sk_buff *skb = bf->bf_mpdu; 262 dma_unmap_single(sc->dev, bf->bf_buf_addr, 263 skb->len, DMA_TO_DEVICE); 264 dev_kfree_skb_any(skb); 265 bf->bf_mpdu = NULL; 266 bf->bf_buf_addr = 0; 267 } 268 269 avp->av_bcbuf = NULL; 270 avp->is_bslot_active = false; 271 sc->beacon.bslot[avp->av_bslot] = NULL; 272 sc->nbcnvifs--; 273 list_add_tail(&bf->list, &sc->beacon.bbuf); 274 275 tasklet_enable(&sc->bcon_tasklet); 276} 277 278void ath_beacon_tasklet(unsigned long data) 279{ 280 struct ath_softc *sc = (struct ath_softc *)data; 281 struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; 282 struct ath_hw *ah = sc->sc_ah; 283 struct ath_common *common = ath9k_hw_common(ah); 284 struct ath_buf *bf = NULL; 285 struct ieee80211_vif *vif; 286 bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); 287 int slot; 288 u32 bfaddr, bc = 0; 289 290 if (work_pending(&sc->hw_reset_work)) { 291 ath_dbg(common, RESET, 292 "reset work is pending, skip beaconing now\n"); 293 return; 294 } 295 /* 296 * Check if the previous beacon has gone out. If 297 * not don't try to post another, skip this period 298 * and wait for the next. Missed beacons indicate 299 * a problem and should not occur. If we miss too 300 * many consecutive beacons reset the device. 301 */ 302 if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) { 303 sc->beacon.bmisscnt++; 304 305 if (!ath9k_hw_check_alive(ah)) 306 ieee80211_queue_work(sc->hw, &sc->hw_check_work); 307 308 if (sc->beacon.bmisscnt < BSTUCK_THRESH * sc->nbcnvifs) { 309 ath_dbg(common, BSTUCK, 310 "missed %u consecutive beacons\n", 311 sc->beacon.bmisscnt); 312 ath9k_hw_stop_dma_queue(ah, sc->beacon.beaconq); 313 if (sc->beacon.bmisscnt > 3) 314 ath9k_hw_bstuck_nfcal(ah); 315 } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) { 316 ath_dbg(common, BSTUCK, "beacon is officially stuck\n"); 317 sc->beacon.bmisscnt = 0; 318 set_bit(SC_OP_TSF_RESET, &sc->sc_flags); 319 ieee80211_queue_work(sc->hw, &sc->hw_reset_work); 320 } 321 322 return; 323 } 324 325 /* 326 * Generate beacon frames. we are sending frames 327 * staggered so calculate the slot for this frame based 328 * on the tsf to safeguard against missing an swba. 329 */ 330 331 332 if (ah->opmode == NL80211_IFTYPE_AP) { 333 u16 intval; 334 u32 tsftu; 335 u64 tsf; 336 337 intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL; 338 tsf = ath9k_hw_gettsf64(ah); 339 tsf += TU_TO_USEC(ah->config.sw_beacon_response_time); 340 tsftu = TSF_TO_TU((tsf * ATH_BCBUF) >>32, tsf * ATH_BCBUF); 341 slot = (tsftu % (intval * ATH_BCBUF)) / intval; 342 vif = sc->beacon.bslot[slot]; 343 344 ath_dbg(common, BEACON, 345 "slot %d [tsf %llu tsftu %u intval %u] vif %p\n", 346 slot, tsf, tsftu / ATH_BCBUF, intval, vif); 347 } else { 348 slot = 0; 349 vif = sc->beacon.bslot[slot]; 350 } 351 352 353 bfaddr = 0; 354 if (vif) { 355 bf = ath_beacon_generate(sc->hw, vif); 356 if (bf != NULL) { 357 bfaddr = bf->bf_daddr; 358 bc = 1; 359 } 360 361 if (sc->beacon.bmisscnt != 0) { 362 ath_dbg(common, BSTUCK, 363 "resume beacon xmit after %u misses\n", 364 sc->beacon.bmisscnt); 365 sc->beacon.bmisscnt = 0; 366 } 367 } 368 369 /* 370 * Handle slot time change when a non-ERP station joins/leaves 371 * an 11g network. The 802.11 layer notifies us via callback, 372 * we mark updateslot, then wait one beacon before effecting 373 * the change. This gives associated stations at least one 374 * beacon interval to note the state change. 375 * 376 * NB: The slot time change state machine is clocked according 377 * to whether we are bursting or staggering beacons. We 378 * recognize the request to update and record the current 379 * slot then don't transition until that slot is reached 380 * again. If we miss a beacon for that slot then we'll be 381 * slow to transition but we'll be sure at least one beacon 382 * interval has passed. When bursting slot is always left 383 * set to ATH_BCBUF so this check is a noop. 384 */ 385 if (sc->beacon.updateslot == UPDATE) { 386 sc->beacon.updateslot = COMMIT; /* commit next beacon */ 387 sc->beacon.slotupdate = slot; 388 } else if (sc->beacon.updateslot == COMMIT && sc->beacon.slotupdate == slot) { 389 ah->slottime = sc->beacon.slottime; 390 ath9k_hw_init_global_settings(ah); 391 sc->beacon.updateslot = OK; 392 } 393 if (bfaddr != 0) { 394 /* NB: cabq traffic should already be queued and primed */ 395 ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bfaddr); 396 397 if (!edma) 398 ath9k_hw_txstart(ah, sc->beacon.beaconq); 399 400 sc->beacon.ast_be_xmit += bc; /* XXX per-vif? */ 401 } 402} 403 404static void ath9k_beacon_init(struct ath_softc *sc, 405 u32 next_beacon, 406 u32 beacon_period) 407{ 408 if (test_bit(SC_OP_TSF_RESET, &sc->sc_flags)) { 409 ath9k_ps_wakeup(sc); 410 ath9k_hw_reset_tsf(sc->sc_ah); 411 } 412 413 ath9k_hw_beaconinit(sc->sc_ah, next_beacon, beacon_period); 414 415 if (test_bit(SC_OP_TSF_RESET, &sc->sc_flags)) { 416 ath9k_ps_restore(sc); 417 clear_bit(SC_OP_TSF_RESET, &sc->sc_flags); 418 } 419} 420 421/* 422 * For multi-bss ap support beacons are either staggered evenly over N slots or 423 * burst together. For the former arrange for the SWBA to be delivered for each 424 * slot. Slots that are not occupied will generate nothing. 425 */ 426static void ath_beacon_config_ap(struct ath_softc *sc, 427 struct ath_beacon_config *conf) 428{ 429 struct ath_hw *ah = sc->sc_ah; 430 u32 nexttbtt, intval; 431 432 /* NB: the beacon interval is kept internally in TU's */ 433 intval = TU_TO_USEC(conf->beacon_interval); 434 intval /= ATH_BCBUF; /* for staggered beacons */ 435 nexttbtt = intval; 436 437 /* 438 * In AP mode we enable the beacon timers and SWBA interrupts to 439 * prepare beacon frames. 440 */ 441 ah->imask |= ATH9K_INT_SWBA; 442 ath_beaconq_config(sc); 443 444 /* Set the computed AP beacon timers */ 445 446 ath9k_hw_disable_interrupts(ah); 447 set_bit(SC_OP_TSF_RESET, &sc->sc_flags); 448 ath9k_beacon_init(sc, nexttbtt, intval); 449 sc->beacon.bmisscnt = 0; 450 ath9k_hw_set_interrupts(ah); 451 ath9k_hw_enable_interrupts(ah); 452} 453 454/* 455 * This sets up the beacon timers according to the timestamp of the last 456 * received beacon and the current TSF, configures PCF and DTIM 457 * handling, programs the sleep registers so the hardware will wakeup in 458 * time to receive beacons, and configures the beacon miss handling so 459 * we'll receive a BMISS interrupt when we stop seeing beacons from the AP 460 * we've associated with. 461 */ 462static void ath_beacon_config_sta(struct ath_softc *sc, 463 struct ath_beacon_config *conf) 464{ 465 struct ath_hw *ah = sc->sc_ah; 466 struct ath_common *common = ath9k_hw_common(ah); 467 struct ath9k_beacon_state bs; 468 int dtimperiod, dtimcount, sleepduration; 469 int cfpperiod, cfpcount; 470 u32 nexttbtt = 0, intval, tsftu; 471 u64 tsf; 472 int num_beacons, offset, dtim_dec_count, cfp_dec_count; 473 474 /* No need to configure beacon if we are not associated */ 475 if (!common->curaid) { 476 ath_dbg(common, BEACON, 477 "STA is not yet associated..skipping beacon config\n"); 478 return; 479 } 480 481 memset(&bs, 0, sizeof(bs)); 482 intval = conf->beacon_interval; 483 484 /* 485 * Setup dtim and cfp parameters according to 486 * last beacon we received (which may be none). 487 */ 488 dtimperiod = conf->dtim_period; 489 dtimcount = conf->dtim_count; 490 if (dtimcount >= dtimperiod) /* NB: sanity check */ 491 dtimcount = 0; 492 cfpperiod = 1; /* NB: no PCF support yet */ 493 cfpcount = 0; 494 495 sleepduration = conf->listen_interval * intval; 496 497 /* 498 * Pull nexttbtt forward to reflect the current 499 * TSF and calculate dtim+cfp state for the result. 500 */ 501 tsf = ath9k_hw_gettsf64(ah); 502 tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE; 503 504 num_beacons = tsftu / intval + 1; 505 offset = tsftu % intval; 506 nexttbtt = tsftu - offset; 507 if (offset) 508 nexttbtt += intval; 509 510 /* DTIM Beacon every dtimperiod Beacon */ 511 dtim_dec_count = num_beacons % dtimperiod; 512 /* CFP every cfpperiod DTIM Beacon */ 513 cfp_dec_count = (num_beacons / dtimperiod) % cfpperiod; 514 if (dtim_dec_count) 515 cfp_dec_count++; 516 517 dtimcount -= dtim_dec_count; 518 if (dtimcount < 0) 519 dtimcount += dtimperiod; 520 521 cfpcount -= cfp_dec_count; 522 if (cfpcount < 0) 523 cfpcount += cfpperiod; 524 525 bs.bs_intval = intval; 526 bs.bs_nexttbtt = nexttbtt; 527 bs.bs_dtimperiod = dtimperiod*intval; 528 bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount*intval; 529 bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod; 530 bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod; 531 bs.bs_cfpmaxduration = 0; 532 533 /* 534 * Calculate the number of consecutive beacons to miss* before taking 535 * a BMISS interrupt. The configuration is specified in TU so we only 536 * need calculate based on the beacon interval. Note that we clamp the 537 * result to at most 15 beacons. 538 */ 539 if (sleepduration > intval) { 540 bs.bs_bmissthreshold = conf->listen_interval * 541 ATH_DEFAULT_BMISS_LIMIT / 2; 542 } else { 543 bs.bs_bmissthreshold = DIV_ROUND_UP(conf->bmiss_timeout, intval); 544 if (bs.bs_bmissthreshold > 15) 545 bs.bs_bmissthreshold = 15; 546 else if (bs.bs_bmissthreshold <= 0) 547 bs.bs_bmissthreshold = 1; 548 } 549 550 /* 551 * Calculate sleep duration. The configuration is given in ms. 552 * We ensure a multiple of the beacon period is used. Also, if the sleep 553 * duration is greater than the DTIM period then it makes senses 554 * to make it a multiple of that. 555 * 556 * XXX fixed at 100ms 557 */ 558 559 bs.bs_sleepduration = roundup(IEEE80211_MS_TO_TU(100), sleepduration); 560 if (bs.bs_sleepduration > bs.bs_dtimperiod) 561 bs.bs_sleepduration = bs.bs_dtimperiod; 562 563 /* TSF out of range threshold fixed at 1 second */ 564 bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD; 565 566 ath_dbg(common, BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu); 567 ath_dbg(common, BEACON, 568 "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n", 569 bs.bs_bmissthreshold, bs.bs_sleepduration, 570 bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext); 571 572 /* Set the computed STA beacon timers */ 573 574 ath9k_hw_disable_interrupts(ah); 575 ath9k_hw_set_sta_beacon_timers(ah, &bs); 576 ah->imask |= ATH9K_INT_BMISS; 577 578 ath9k_hw_set_interrupts(ah); 579 ath9k_hw_enable_interrupts(ah); 580} 581 582static void ath_beacon_config_adhoc(struct ath_softc *sc, 583 struct ath_beacon_config *conf) 584{ 585 struct ath_hw *ah = sc->sc_ah; 586 struct ath_common *common = ath9k_hw_common(ah); 587 u32 tsf, intval, nexttbtt; 588 589 ath9k_reset_beacon_status(sc); 590 if (!test_bit(SC_OP_BEACONS, &sc->sc_flags)) 591 ath9k_hw_settsf64(ah, sc->beacon.bc_tstamp); 592 593 intval = TU_TO_USEC(conf->beacon_interval); 594 tsf = roundup(ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE), intval); 595 nexttbtt = tsf + intval; 596 597 ath_dbg(common, BEACON, "IBSS nexttbtt %u intval %u (%u)\n", 598 nexttbtt, intval, conf->beacon_interval); 599 600 /* 601 * In IBSS mode enable the beacon timers but only enable SWBA interrupts 602 * if we need to manually prepare beacon frames. Otherwise we use a 603 * self-linked tx descriptor and let the hardware deal with things. 604 */ 605 ah->imask |= ATH9K_INT_SWBA; 606 607 ath_beaconq_config(sc); 608 609 /* Set the computed ADHOC beacon timers */ 610 611 ath9k_hw_disable_interrupts(ah); 612 ath9k_beacon_init(sc, nexttbtt, intval); 613 sc->beacon.bmisscnt = 0; 614 615 ath9k_hw_set_interrupts(ah); 616 ath9k_hw_enable_interrupts(ah); 617} 618 619static bool ath9k_allow_beacon_config(struct ath_softc *sc, 620 struct ieee80211_vif *vif) 621{ 622 struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; 623 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 624 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; 625 struct ath_vif *avp = (void *)vif->drv_priv; 626 627 /* 628 * Can not have different beacon interval on multiple 629 * AP interface case 630 */ 631 if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) && 632 (sc->nbcnvifs > 1) && 633 (vif->type == NL80211_IFTYPE_AP) && 634 (cur_conf->beacon_interval != bss_conf->beacon_int)) { 635 ath_dbg(common, CONFIG, 636 "Changing beacon interval of multiple AP interfaces !\n"); 637 return false; 638 } 639 /* 640 * Can not configure station vif's beacon config 641 * while on AP opmode 642 */ 643 if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) && 644 (vif->type != NL80211_IFTYPE_AP)) { 645 ath_dbg(common, CONFIG, 646 "STA vif's beacon not allowed on AP mode\n"); 647 return false; 648 } 649 /* 650 * Do not allow beacon config if HW was already configured 651 * with another STA vif 652 */ 653 if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) && 654 (vif->type == NL80211_IFTYPE_STATION) && 655 test_bit(SC_OP_BEACONS, &sc->sc_flags) && 656 !avp->primary_sta_vif) { 657 ath_dbg(common, CONFIG, 658 "Beacon already configured for a station interface\n"); 659 return false; 660 } 661 return true; 662} 663 664void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) 665{ 666 struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; 667 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; 668 669 if (!ath9k_allow_beacon_config(sc, vif)) 670 return; 671 672 /* Setup the beacon configuration parameters */ 673 cur_conf->beacon_interval = bss_conf->beacon_int; 674 cur_conf->dtim_period = bss_conf->dtim_period; 675 cur_conf->listen_interval = 1; 676 cur_conf->dtim_count = 1; 677 cur_conf->bmiss_timeout = 678 ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval; 679 680 /* 681 * It looks like mac80211 may end up using beacon interval of zero in 682 * some cases (at least for mesh point). Avoid getting into an 683 * infinite loop by using a bit safer value instead. To be safe, 684 * do sanity check on beacon interval for all operating modes. 685 */ 686 if (cur_conf->beacon_interval == 0) 687 cur_conf->beacon_interval = 100; 688 689 /* 690 * We don't parse dtim period from mac80211 during the driver 691 * initialization as it breaks association with hidden-ssid 692 * AP and it causes latency in roaming 693 */ 694 if (cur_conf->dtim_period == 0) 695 cur_conf->dtim_period = 1; 696 697 ath_set_beacon(sc); 698} 699 700static bool ath_has_valid_bslot(struct ath_softc *sc) 701{ 702 struct ath_vif *avp; 703 int slot; 704 bool found = false; 705 706 for (slot = 0; slot < ATH_BCBUF; slot++) { 707 if (sc->beacon.bslot[slot]) { 708 avp = (void *)sc->beacon.bslot[slot]->drv_priv; 709 if (avp->is_bslot_active) { 710 found = true; 711 break; 712 } 713 } 714 } 715 return found; 716} 717 718 719void ath_set_beacon(struct ath_softc *sc) 720{ 721 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 722 struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; 723 724 switch (sc->sc_ah->opmode) { 725 case NL80211_IFTYPE_AP: 726 if (ath_has_valid_bslot(sc)) 727 ath_beacon_config_ap(sc, cur_conf); 728 break; 729 case NL80211_IFTYPE_ADHOC: 730 case NL80211_IFTYPE_MESH_POINT: 731 ath_beacon_config_adhoc(sc, cur_conf); 732 break; 733 case NL80211_IFTYPE_STATION: 734 ath_beacon_config_sta(sc, cur_conf); 735 break; 736 default: 737 ath_dbg(common, CONFIG, "Unsupported beaconing mode\n"); 738 return; 739 } 740 741 set_bit(SC_OP_BEACONS, &sc->sc_flags); 742} 743 744void ath9k_set_beaconing_status(struct ath_softc *sc, bool status) 745{ 746 struct ath_hw *ah = sc->sc_ah; 747 748 if (!ath_has_valid_bslot(sc)) { 749 clear_bit(SC_OP_BEACONS, &sc->sc_flags); 750 return; 751 } 752 753 ath9k_ps_wakeup(sc); 754 if (status) { 755 /* Re-enable beaconing */ 756 ah->imask |= ATH9K_INT_SWBA; 757 ath9k_hw_set_interrupts(ah); 758 } else { 759 /* Disable SWBA interrupt */ 760 ah->imask &= ~ATH9K_INT_SWBA; 761 ath9k_hw_set_interrupts(ah); 762 tasklet_kill(&sc->bcon_tasklet); 763 ath9k_hw_stop_dma_queue(ah, sc->beacon.beaconq); 764 } 765 ath9k_ps_restore(sc); 766} 767