aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c88
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c2
2 files changed, 45 insertions, 45 deletions
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 5128856d77d2..78ffe762e26c 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -431,6 +431,33 @@ static void ath9k_beacon_init(struct ath_softc *sc, u32 nexttbtt,
431 ath9k_hw_enable_interrupts(ah); 431 ath9k_hw_enable_interrupts(ah);
432} 432}
433 433
434/* Calculate the modulo of a 64 bit TSF snapshot with a TU divisor */
435static u32 ath9k_mod_tsf64_tu(u64 tsf, u32 div_tu)
436{
437 u32 tsf_mod, tsf_hi, tsf_lo, mod_hi, mod_lo;
438
439 tsf_mod = tsf & (BIT(10) - 1);
440 tsf_hi = tsf >> 32;
441 tsf_lo = ((u32) tsf) >> 10;
442
443 mod_hi = tsf_hi % div_tu;
444 mod_lo = ((mod_hi << 22) + tsf_lo) % div_tu;
445
446 return (mod_lo << 10) | tsf_mod;
447}
448
449static u32 ath9k_get_next_tbtt(struct ath_softc *sc, u64 tsf,
450 unsigned int interval)
451{
452 struct ath_hw *ah = sc->sc_ah;
453 unsigned int offset;
454
455 tsf += TU_TO_USEC(FUDGE + ah->config.sw_beacon_response_time);
456 offset = ath9k_mod_tsf64_tu(tsf, interval);
457
458 return (u32) tsf + TU_TO_USEC(interval) - offset;
459}
460
434/* 461/*
435 * For multi-bss ap support beacons are either staggered evenly over N slots or 462 * For multi-bss ap support beacons are either staggered evenly over N slots or
436 * burst together. For the former arrange for the SWBA to be delivered for each 463 * burst together. For the former arrange for the SWBA to be delivered for each
@@ -446,7 +473,8 @@ static void ath9k_beacon_config_ap(struct ath_softc *sc,
446 /* NB: the beacon interval is kept internally in TU's */ 473 /* NB: the beacon interval is kept internally in TU's */
447 intval = TU_TO_USEC(conf->beacon_interval); 474 intval = TU_TO_USEC(conf->beacon_interval);
448 intval /= ATH_BCBUF; 475 intval /= ATH_BCBUF;
449 nexttbtt = intval; 476 nexttbtt = ath9k_get_next_tbtt(sc, ath9k_hw_gettsf64(ah),
477 conf->beacon_interval);
450 478
451 if (conf->enable_beacon) 479 if (conf->enable_beacon)
452 ah->imask |= ATH9K_INT_SWBA; 480 ah->imask |= ATH9K_INT_SWBA;
@@ -458,7 +486,7 @@ static void ath9k_beacon_config_ap(struct ath_softc *sc,
458 (conf->enable_beacon) ? "Enable" : "Disable", 486 (conf->enable_beacon) ? "Enable" : "Disable",
459 nexttbtt, intval, conf->beacon_interval); 487 nexttbtt, intval, conf->beacon_interval);
460 488
461 ath9k_beacon_init(sc, nexttbtt, intval, true); 489 ath9k_beacon_init(sc, nexttbtt, intval, false);
462} 490}
463 491
464/* 492/*
@@ -475,10 +503,9 @@ static void ath9k_beacon_config_sta(struct ath_softc *sc,
475 struct ath_hw *ah = sc->sc_ah; 503 struct ath_hw *ah = sc->sc_ah;
476 struct ath_common *common = ath9k_hw_common(ah); 504 struct ath_common *common = ath9k_hw_common(ah);
477 struct ath9k_beacon_state bs; 505 struct ath9k_beacon_state bs;
478 int dtimperiod, dtimcount, sleepduration; 506 int dtim_intval, sleepduration;
479 u32 nexttbtt = 0, intval, tsftu; 507 u32 nexttbtt = 0, intval;
480 u64 tsf; 508 u64 tsf;
481 int num_beacons, offset, dtim_dec_count;
482 509
483 /* No need to configure beacon if we are not associated */ 510 /* No need to configure beacon if we are not associated */
484 if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) { 511 if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) {
@@ -494,11 +521,7 @@ static void ath9k_beacon_config_sta(struct ath_softc *sc,
494 * Setup dtim parameters according to 521 * Setup dtim parameters according to
495 * last beacon we received (which may be none). 522 * last beacon we received (which may be none).
496 */ 523 */
497 dtimperiod = conf->dtim_period; 524 dtim_intval = intval * conf->dtim_period;
498 dtimcount = conf->dtim_count;
499 if (dtimcount >= dtimperiod) /* NB: sanity check */
500 dtimcount = 0;
501
502 sleepduration = conf->listen_interval * intval; 525 sleepduration = conf->listen_interval * intval;
503 526
504 /* 527 /*
@@ -506,24 +529,14 @@ static void ath9k_beacon_config_sta(struct ath_softc *sc,
506 * TSF and calculate dtim state for the result. 529 * TSF and calculate dtim state for the result.
507 */ 530 */
508 tsf = ath9k_hw_gettsf64(ah); 531 tsf = ath9k_hw_gettsf64(ah);
509 tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE; 532 nexttbtt = ath9k_get_next_tbtt(sc, tsf, intval);
510
511 num_beacons = tsftu / intval + 1;
512 offset = tsftu % intval;
513 nexttbtt = tsftu - offset;
514 if (offset)
515 nexttbtt += intval;
516
517 /* DTIM Beacon every dtimperiod Beacon */
518 dtim_dec_count = num_beacons % dtimperiod;
519 dtimcount -= dtim_dec_count;
520 if (dtimcount < 0)
521 dtimcount += dtimperiod;
522 533
523 bs.bs_intval = TU_TO_USEC(intval); 534 bs.bs_intval = TU_TO_USEC(intval);
524 bs.bs_nexttbtt = TU_TO_USEC(nexttbtt); 535 bs.bs_dtimperiod = conf->dtim_period * bs.bs_intval;
525 bs.bs_dtimperiod = dtimperiod * bs.bs_intval; 536 bs.bs_nexttbtt = nexttbtt;
526 bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount * bs.bs_intval; 537 bs.bs_nextdtim = nexttbtt;
538 if (conf->dtim_period > 1)
539 bs.bs_nextdtim = ath9k_get_next_tbtt(sc, tsf, dtim_intval);
527 540
528 /* 541 /*
529 * Calculate the number of consecutive beacons to miss* before taking 542 * Calculate the number of consecutive beacons to miss* before taking
@@ -559,7 +572,6 @@ static void ath9k_beacon_config_sta(struct ath_softc *sc,
559 /* TSF out of range threshold fixed at 1 second */ 572 /* TSF out of range threshold fixed at 1 second */
560 bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD; 573 bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD;
561 574
562 ath_dbg(common, BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu);
563 ath_dbg(common, BEACON, "bmiss: %u sleep: %u\n", 575 ath_dbg(common, BEACON, "bmiss: %u sleep: %u\n",
564 bs.bs_bmissthreshold, bs.bs_sleepduration); 576 bs.bs_bmissthreshold, bs.bs_sleepduration);
565 577
@@ -584,25 +596,11 @@ static void ath9k_beacon_config_adhoc(struct ath_softc *sc,
584 596
585 intval = TU_TO_USEC(conf->beacon_interval); 597 intval = TU_TO_USEC(conf->beacon_interval);
586 598
587 if (conf->ibss_creator) { 599 if (conf->ibss_creator)
588 nexttbtt = intval; 600 nexttbtt = intval;
589 } else { 601 else
590 u32 tbtt, offset, tsftu; 602 nexttbtt = ath9k_get_next_tbtt(sc, ath9k_hw_gettsf64(ah),
591 u64 tsf; 603 conf->beacon_interval);
592
593 /*
594 * Pull nexttbtt forward to reflect the current
595 * sync'd TSF.
596 */
597 tsf = ath9k_hw_gettsf64(ah);
598 tsftu = TSF_TO_TU(tsf >> 32, tsf) + FUDGE;
599 offset = tsftu % conf->beacon_interval;
600 tbtt = tsftu - offset;
601 if (offset)
602 tbtt += conf->beacon_interval;
603
604 nexttbtt = TU_TO_USEC(tbtt);
605 }
606 604
607 if (conf->enable_beacon) 605 if (conf->enable_beacon)
608 ah->imask |= ATH9K_INT_SWBA; 606 ah->imask |= ATH9K_INT_SWBA;
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 4798f6ae061e..6a231201c7dc 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -760,6 +760,8 @@ static int ath9k_start(struct ieee80211_hw *hw)
760 */ 760 */
761 ath9k_cmn_init_crypto(sc->sc_ah); 761 ath9k_cmn_init_crypto(sc->sc_ah);
762 762
763 ath9k_hw_reset_tsf(ah);
764
763 spin_unlock_bh(&sc->sc_pcu_lock); 765 spin_unlock_bh(&sc->sc_pcu_lock);
764 766
765 mutex_unlock(&sc->mutex); 767 mutex_unlock(&sc->mutex);