diff options
author | Sujith Manoharan <c_manoha@qca.qualcomm.com> | 2012-07-17 07:46:29 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-07-17 15:11:39 -0400 |
commit | da0d45f7b1dd08ab1ea4f542db797a0c51724281 (patch) | |
tree | 8e2c4a4eac44c4650a09b51d04d7148052dfff1a | |
parent | fb6e252f8d262d05da3ae023b4a6f83d0eec17d9 (diff) |
ath9k: Fix ANI management
Currently, there are problems with how ANI is handled in
multi-VIF scenarios. This patch addresses them by unifying
the start/stop logic.
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ath9k.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/debug.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/link.c | 60 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 29 |
4 files changed, 70 insertions, 28 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 41219a5e7f53..c8af0db97c4f 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -447,7 +447,9 @@ void ath_rx_poll(unsigned long data); | |||
447 | void ath_start_rx_poll(struct ath_softc *sc, u8 nbeacon); | 447 | void ath_start_rx_poll(struct ath_softc *sc, u8 nbeacon); |
448 | void ath_paprd_calibrate(struct work_struct *work); | 448 | void ath_paprd_calibrate(struct work_struct *work); |
449 | void ath_ani_calibrate(unsigned long data); | 449 | void ath_ani_calibrate(unsigned long data); |
450 | void ath_start_ani(struct ath_common *common); | 450 | void ath_start_ani(struct ath_softc *sc); |
451 | void ath_stop_ani(struct ath_softc *sc); | ||
452 | void ath_check_ani(struct ath_softc *sc); | ||
451 | int ath_update_survey_stats(struct ath_softc *sc); | 453 | int ath_update_survey_stats(struct ath_softc *sc); |
452 | void ath_update_survey_nf(struct ath_softc *sc, int channel); | 454 | void ath_update_survey_nf(struct ath_softc *sc, int channel); |
453 | 455 | ||
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index b9ea067a7bb5..68b643c8943c 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -206,10 +206,9 @@ static ssize_t write_file_disable_ani(struct file *file, | |||
206 | 206 | ||
207 | if (disable_ani) { | 207 | if (disable_ani) { |
208 | clear_bit(SC_OP_ANI_RUN, &sc->sc_flags); | 208 | clear_bit(SC_OP_ANI_RUN, &sc->sc_flags); |
209 | del_timer_sync(&common->ani.timer); | 209 | ath_stop_ani(sc); |
210 | } else { | 210 | } else { |
211 | set_bit(SC_OP_ANI_RUN, &sc->sc_flags); | 211 | ath_check_ani(sc); |
212 | ath_start_ani(common); | ||
213 | } | 212 | } |
214 | 213 | ||
215 | return count; | 214 | return count; |
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c index 91650fe50461..42fc0a374c61 100644 --- a/drivers/net/wireless/ath/ath9k/link.c +++ b/drivers/net/wireless/ath/ath9k/link.c | |||
@@ -432,26 +432,72 @@ set_timer: | |||
432 | } | 432 | } |
433 | } | 433 | } |
434 | 434 | ||
435 | void ath_start_ani(struct ath_common *common) | 435 | void ath_start_ani(struct ath_softc *sc) |
436 | { | 436 | { |
437 | struct ath_hw *ah = common->ah; | 437 | struct ath_hw *ah = sc->sc_ah; |
438 | struct ath_common *common = ath9k_hw_common(ah); | ||
438 | unsigned long timestamp = jiffies_to_msecs(jiffies); | 439 | unsigned long timestamp = jiffies_to_msecs(jiffies); |
439 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
440 | |||
441 | if (!test_bit(SC_OP_ANI_RUN, &sc->sc_flags)) | ||
442 | return; | ||
443 | 440 | ||
444 | if (sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) | 441 | if (common->disable_ani || |
442 | !test_bit(SC_OP_ANI_RUN, &sc->sc_flags) || | ||
443 | (sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) | ||
445 | return; | 444 | return; |
446 | 445 | ||
447 | common->ani.longcal_timer = timestamp; | 446 | common->ani.longcal_timer = timestamp; |
448 | common->ani.shortcal_timer = timestamp; | 447 | common->ani.shortcal_timer = timestamp; |
449 | common->ani.checkani_timer = timestamp; | 448 | common->ani.checkani_timer = timestamp; |
450 | 449 | ||
450 | ath_dbg(common, ANI, "Starting ANI\n"); | ||
451 | mod_timer(&common->ani.timer, | 451 | mod_timer(&common->ani.timer, |
452 | jiffies + msecs_to_jiffies((u32)ah->config.ani_poll_interval)); | 452 | jiffies + msecs_to_jiffies((u32)ah->config.ani_poll_interval)); |
453 | } | 453 | } |
454 | 454 | ||
455 | void ath_stop_ani(struct ath_softc *sc) | ||
456 | { | ||
457 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
458 | |||
459 | ath_dbg(common, ANI, "Stopping ANI\n"); | ||
460 | del_timer_sync(&common->ani.timer); | ||
461 | } | ||
462 | |||
463 | void ath_check_ani(struct ath_softc *sc) | ||
464 | { | ||
465 | struct ath_hw *ah = sc->sc_ah; | ||
466 | struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; | ||
467 | |||
468 | /* | ||
469 | * Check for the various conditions in which ANI has to | ||
470 | * be stopped. | ||
471 | */ | ||
472 | if (ah->opmode == NL80211_IFTYPE_ADHOC) { | ||
473 | if (!cur_conf->enable_beacon) | ||
474 | goto stop_ani; | ||
475 | } else if (ah->opmode == NL80211_IFTYPE_AP) { | ||
476 | if (!cur_conf->enable_beacon) { | ||
477 | /* | ||
478 | * Disable ANI only when there are no | ||
479 | * associated stations. | ||
480 | */ | ||
481 | if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) | ||
482 | goto stop_ani; | ||
483 | } | ||
484 | } else if (ah->opmode == NL80211_IFTYPE_STATION) { | ||
485 | if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) | ||
486 | goto stop_ani; | ||
487 | } | ||
488 | |||
489 | if (!test_bit(SC_OP_ANI_RUN, &sc->sc_flags)) { | ||
490 | set_bit(SC_OP_ANI_RUN, &sc->sc_flags); | ||
491 | ath_start_ani(sc); | ||
492 | } | ||
493 | |||
494 | return; | ||
495 | |||
496 | stop_ani: | ||
497 | clear_bit(SC_OP_ANI_RUN, &sc->sc_flags); | ||
498 | ath_stop_ani(sc); | ||
499 | } | ||
500 | |||
455 | void ath_update_survey_nf(struct ath_softc *sc, int channel) | 501 | void ath_update_survey_nf(struct ath_softc *sc, int channel) |
456 | { | 502 | { |
457 | struct ath_hw *ah = sc->sc_ah; | 503 | struct ath_hw *ah = sc->sc_ah; |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 915bd4881b3f..d80d5be2ccb7 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -167,8 +167,6 @@ static void ath_cancel_work(struct ath_softc *sc) | |||
167 | 167 | ||
168 | static void ath_restart_work(struct ath_softc *sc) | 168 | static void ath_restart_work(struct ath_softc *sc) |
169 | { | 169 | { |
170 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
171 | |||
172 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); | 170 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); |
173 | 171 | ||
174 | if (AR_SREV_9340(sc->sc_ah) || AR_SREV_9485(sc->sc_ah) || | 172 | if (AR_SREV_9340(sc->sc_ah) || AR_SREV_9485(sc->sc_ah) || |
@@ -177,21 +175,18 @@ static void ath_restart_work(struct ath_softc *sc) | |||
177 | msecs_to_jiffies(ATH_PLL_WORK_INTERVAL)); | 175 | msecs_to_jiffies(ATH_PLL_WORK_INTERVAL)); |
178 | 176 | ||
179 | ath_start_rx_poll(sc, 3); | 177 | ath_start_rx_poll(sc, 3); |
180 | 178 | ath_start_ani(sc); | |
181 | if (!common->disable_ani) | ||
182 | ath_start_ani(common); | ||
183 | } | 179 | } |
184 | 180 | ||
185 | static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush) | 181 | static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush) |
186 | { | 182 | { |
187 | struct ath_hw *ah = sc->sc_ah; | 183 | struct ath_hw *ah = sc->sc_ah; |
188 | struct ath_common *common = ath9k_hw_common(ah); | ||
189 | bool ret = true; | 184 | bool ret = true; |
190 | 185 | ||
191 | ieee80211_stop_queues(sc->hw); | 186 | ieee80211_stop_queues(sc->hw); |
192 | 187 | ||
193 | sc->hw_busy_count = 0; | 188 | sc->hw_busy_count = 0; |
194 | del_timer_sync(&common->ani.timer); | 189 | ath_stop_ani(sc); |
195 | del_timer_sync(&sc->rx_poll_timer); | 190 | del_timer_sync(&sc->rx_poll_timer); |
196 | 191 | ||
197 | ath9k_debug_samp_bb_mac(sc); | 192 | ath9k_debug_samp_bb_mac(sc); |
@@ -1481,6 +1476,11 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
1481 | struct ieee80211_bss_conf *bss_conf, | 1476 | struct ieee80211_bss_conf *bss_conf, |
1482 | u32 changed) | 1477 | u32 changed) |
1483 | { | 1478 | { |
1479 | #define CHECK_ANI \ | ||
1480 | (BSS_CHANGED_ASSOC | \ | ||
1481 | BSS_CHANGED_IBSS | \ | ||
1482 | BSS_CHANGED_BEACON_ENABLED) | ||
1483 | |||
1484 | struct ath_softc *sc = hw->priv; | 1484 | struct ath_softc *sc = hw->priv; |
1485 | struct ath_hw *ah = sc->sc_ah; | 1485 | struct ath_hw *ah = sc->sc_ah; |
1486 | struct ath_common *common = ath9k_hw_common(ah); | 1486 | struct ath_common *common = ath9k_hw_common(ah); |
@@ -1517,16 +1517,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
1517 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); | 1517 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); |
1518 | common->curaid = bss_conf->aid; | 1518 | common->curaid = bss_conf->aid; |
1519 | ath9k_hw_write_associd(sc->sc_ah); | 1519 | ath9k_hw_write_associd(sc->sc_ah); |
1520 | |||
1521 | if (bss_conf->ibss_joined) { | ||
1522 | if (!common->disable_ani) { | ||
1523 | set_bit(SC_OP_ANI_RUN, &sc->sc_flags); | ||
1524 | ath_start_ani(common); | ||
1525 | } | ||
1526 | } else { | ||
1527 | clear_bit(SC_OP_ANI_RUN, &sc->sc_flags); | ||
1528 | del_timer_sync(&common->ani.timer); | ||
1529 | } | ||
1530 | } | 1520 | } |
1531 | 1521 | ||
1532 | if ((changed & BSS_CHANGED_BEACON_ENABLED) || | 1522 | if ((changed & BSS_CHANGED_BEACON_ENABLED) || |
@@ -1557,8 +1547,13 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
1557 | } | 1547 | } |
1558 | } | 1548 | } |
1559 | 1549 | ||
1550 | if (changed & CHECK_ANI) | ||
1551 | ath_check_ani(sc); | ||
1552 | |||
1560 | mutex_unlock(&sc->mutex); | 1553 | mutex_unlock(&sc->mutex); |
1561 | ath9k_ps_restore(sc); | 1554 | ath9k_ps_restore(sc); |
1555 | |||
1556 | #undef CHECK_ANI | ||
1562 | } | 1557 | } |
1563 | 1558 | ||
1564 | static u64 ath9k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | 1559 | static u64 ath9k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) |