diff options
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/beacon.c | 88 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 2 |
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 */ | ||
| 435 | static 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 | |||
| 449 | static 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); |
