aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorSujith <Sujith.Manoharan@atheros.com>2009-03-02 23:46:56 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-03-05 14:39:42 -0500
commitb238e90e99fe51aed14d20eae8a6a1c04ce4ca30 (patch)
treeb9cd8add0647c0ce98959710d682191300a71a9b /drivers/net/wireless
parent5379c8a26686e12058e23322615df68f9123bccd (diff)
ath9k: Handle TSF properly for AP mode
The TSF has to be reset only once, upon bringing the interface up in AP mode. For any beacon reconfigure calls after that, resetting the TSF results in incorrect beacon generation. The only exception is a change in the beacon interval, which is indicated to the driver by mac80211 through IEEE80211_CONF_CHANGE_BEACON_INTERVAL, handle this properly. Signed-off-by: Sujith <Sujith.Manoharan@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/ath9k/ath9k.h33
-rw-r--r--drivers/net/wireless/ath9k/beacon.c10
-rw-r--r--drivers/net/wireless/ath9k/main.c14
3 files changed, 40 insertions, 17 deletions
diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h
index 0769a252dfe1..4c1da716e6d8 100644
--- a/drivers/net/wireless/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath9k/ath9k.h
@@ -542,22 +542,23 @@ struct ath_rfkill {
542#define ATH_RSSI_DUMMY_MARKER 0x127 542#define ATH_RSSI_DUMMY_MARKER 0x127
543#define ATH_RATE_DUMMY_MARKER 0 543#define ATH_RATE_DUMMY_MARKER 0
544 544
545#define SC_OP_INVALID BIT(0) 545#define SC_OP_INVALID BIT(0)
546#define SC_OP_BEACONS BIT(1) 546#define SC_OP_BEACONS BIT(1)
547#define SC_OP_RXAGGR BIT(2) 547#define SC_OP_RXAGGR BIT(2)
548#define SC_OP_TXAGGR BIT(3) 548#define SC_OP_TXAGGR BIT(3)
549#define SC_OP_CHAINMASK_UPDATE BIT(4) 549#define SC_OP_CHAINMASK_UPDATE BIT(4)
550#define SC_OP_FULL_RESET BIT(5) 550#define SC_OP_FULL_RESET BIT(5)
551#define SC_OP_PREAMBLE_SHORT BIT(6) 551#define SC_OP_PREAMBLE_SHORT BIT(6)
552#define SC_OP_PROTECT_ENABLE BIT(7) 552#define SC_OP_PROTECT_ENABLE BIT(7)
553#define SC_OP_RXFLUSH BIT(8) 553#define SC_OP_RXFLUSH BIT(8)
554#define SC_OP_LED_ASSOCIATED BIT(9) 554#define SC_OP_LED_ASSOCIATED BIT(9)
555#define SC_OP_RFKILL_REGISTERED BIT(10) 555#define SC_OP_RFKILL_REGISTERED BIT(10)
556#define SC_OP_RFKILL_SW_BLOCKED BIT(11) 556#define SC_OP_RFKILL_SW_BLOCKED BIT(11)
557#define SC_OP_RFKILL_HW_BLOCKED BIT(12) 557#define SC_OP_RFKILL_HW_BLOCKED BIT(12)
558#define SC_OP_WAIT_FOR_BEACON BIT(13) 558#define SC_OP_WAIT_FOR_BEACON BIT(13)
559#define SC_OP_LED_ON BIT(14) 559#define SC_OP_LED_ON BIT(14)
560#define SC_OP_SCANNING BIT(15) 560#define SC_OP_SCANNING BIT(15)
561#define SC_OP_TSF_RESET BIT(16)
561 562
562struct ath_bus_ops { 563struct ath_bus_ops {
563 void (*read_cachesize)(struct ath_softc *sc, int *csz); 564 void (*read_cachesize)(struct ath_softc *sc, int *csz);
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c
index 74916431f575..d1365726d2f3 100644
--- a/drivers/net/wireless/ath9k/beacon.c
+++ b/drivers/net/wireless/ath9k/beacon.c
@@ -510,6 +510,11 @@ static void ath_beacon_config_ap(struct ath_softc *sc,
510{ 510{
511 u32 nexttbtt, intval; 511 u32 nexttbtt, intval;
512 512
513 /* Configure the timers only when the TSF has to be reset */
514
515 if (!(sc->sc_flags & SC_OP_TSF_RESET))
516 return;
517
513 /* NB: the beacon interval is kept internally in TU's */ 518 /* NB: the beacon interval is kept internally in TU's */
514 intval = conf->beacon_interval & ATH9K_BEACON_PERIOD; 519 intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
515 intval /= ATH_BCBUF; /* for staggered beacons */ 520 intval /= ATH_BCBUF; /* for staggered beacons */
@@ -530,6 +535,11 @@ static void ath_beacon_config_ap(struct ath_softc *sc,
530 ath9k_hw_beaconinit(sc->sc_ah, nexttbtt, intval); 535 ath9k_hw_beaconinit(sc->sc_ah, nexttbtt, intval);
531 sc->beacon.bmisscnt = 0; 536 sc->beacon.bmisscnt = 0;
532 ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); 537 ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
538
539 /* Clear the reset TSF flag, so that subsequent beacon updation
540 will not reset the HW TSF. */
541
542 sc->sc_flags &= ~SC_OP_TSF_RESET;
533} 543}
534 544
535/* 545/*
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index 9e8f954877c9..a25dcf949f36 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -2168,8 +2168,10 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
2168 avp->av_opmode = ic_opmode; 2168 avp->av_opmode = ic_opmode;
2169 avp->av_bslot = -1; 2169 avp->av_bslot = -1;
2170 2170
2171 if (ic_opmode == NL80211_IFTYPE_AP) 2171 if (ic_opmode == NL80211_IFTYPE_AP) {
2172 ath9k_hw_set_tsfadjust(sc->sc_ah, 1); 2172 ath9k_hw_set_tsfadjust(sc->sc_ah, 1);
2173 sc->sc_flags |= SC_OP_TSF_RESET;
2174 }
2173 2175
2174 sc->vifs[0] = conf->vif; 2176 sc->vifs[0] = conf->vif;
2175 sc->nvifs++; 2177 sc->nvifs++;
@@ -2291,6 +2293,16 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
2291 if (changed & IEEE80211_CONF_CHANGE_POWER) 2293 if (changed & IEEE80211_CONF_CHANGE_POWER)
2292 sc->config.txpowlimit = 2 * conf->power_level; 2294 sc->config.txpowlimit = 2 * conf->power_level;
2293 2295
2296 /*
2297 * The HW TSF has to be reset when the beacon interval changes.
2298 * We set the flag here, and ath_beacon_config_ap() would take this
2299 * into account when it gets called through the subsequent
2300 * config_interface() call - with IFCC_BEACON in the changed field.
2301 */
2302
2303 if (changed & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
2304 sc->sc_flags |= SC_OP_TSF_RESET;
2305
2294 mutex_unlock(&sc->mutex); 2306 mutex_unlock(&sc->mutex);
2295 2307
2296 return 0; 2308 return 0;