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>
This commit is contained in:
parent
fb6e252f8d
commit
da0d45f7b1
|
@ -447,7 +447,9 @@ void ath_rx_poll(unsigned long data);
|
|||
void ath_start_rx_poll(struct ath_softc *sc, u8 nbeacon);
|
||||
void ath_paprd_calibrate(struct work_struct *work);
|
||||
void ath_ani_calibrate(unsigned long data);
|
||||
void ath_start_ani(struct ath_common *common);
|
||||
void ath_start_ani(struct ath_softc *sc);
|
||||
void ath_stop_ani(struct ath_softc *sc);
|
||||
void ath_check_ani(struct ath_softc *sc);
|
||||
int ath_update_survey_stats(struct ath_softc *sc);
|
||||
void ath_update_survey_nf(struct ath_softc *sc, int channel);
|
||||
|
||||
|
|
|
@ -206,10 +206,9 @@ static ssize_t write_file_disable_ani(struct file *file,
|
|||
|
||||
if (disable_ani) {
|
||||
clear_bit(SC_OP_ANI_RUN, &sc->sc_flags);
|
||||
del_timer_sync(&common->ani.timer);
|
||||
ath_stop_ani(sc);
|
||||
} else {
|
||||
set_bit(SC_OP_ANI_RUN, &sc->sc_flags);
|
||||
ath_start_ani(common);
|
||||
ath_check_ani(sc);
|
||||
}
|
||||
|
||||
return count;
|
||||
|
|
|
@ -432,26 +432,72 @@ set_timer:
|
|||
}
|
||||
}
|
||||
|
||||
void ath_start_ani(struct ath_common *common)
|
||||
void ath_start_ani(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_hw *ah = common->ah;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
unsigned long timestamp = jiffies_to_msecs(jiffies);
|
||||
struct ath_softc *sc = (struct ath_softc *) common->priv;
|
||||
|
||||
if (!test_bit(SC_OP_ANI_RUN, &sc->sc_flags))
|
||||
return;
|
||||
|
||||
if (sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
|
||||
if (common->disable_ani ||
|
||||
!test_bit(SC_OP_ANI_RUN, &sc->sc_flags) ||
|
||||
(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL))
|
||||
return;
|
||||
|
||||
common->ani.longcal_timer = timestamp;
|
||||
common->ani.shortcal_timer = timestamp;
|
||||
common->ani.checkani_timer = timestamp;
|
||||
|
||||
ath_dbg(common, ANI, "Starting ANI\n");
|
||||
mod_timer(&common->ani.timer,
|
||||
jiffies + msecs_to_jiffies((u32)ah->config.ani_poll_interval));
|
||||
}
|
||||
|
||||
void ath_stop_ani(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
|
||||
ath_dbg(common, ANI, "Stopping ANI\n");
|
||||
del_timer_sync(&common->ani.timer);
|
||||
}
|
||||
|
||||
void ath_check_ani(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
|
||||
|
||||
/*
|
||||
* Check for the various conditions in which ANI has to
|
||||
* be stopped.
|
||||
*/
|
||||
if (ah->opmode == NL80211_IFTYPE_ADHOC) {
|
||||
if (!cur_conf->enable_beacon)
|
||||
goto stop_ani;
|
||||
} else if (ah->opmode == NL80211_IFTYPE_AP) {
|
||||
if (!cur_conf->enable_beacon) {
|
||||
/*
|
||||
* Disable ANI only when there are no
|
||||
* associated stations.
|
||||
*/
|
||||
if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags))
|
||||
goto stop_ani;
|
||||
}
|
||||
} else if (ah->opmode == NL80211_IFTYPE_STATION) {
|
||||
if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags))
|
||||
goto stop_ani;
|
||||
}
|
||||
|
||||
if (!test_bit(SC_OP_ANI_RUN, &sc->sc_flags)) {
|
||||
set_bit(SC_OP_ANI_RUN, &sc->sc_flags);
|
||||
ath_start_ani(sc);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
stop_ani:
|
||||
clear_bit(SC_OP_ANI_RUN, &sc->sc_flags);
|
||||
ath_stop_ani(sc);
|
||||
}
|
||||
|
||||
void ath_update_survey_nf(struct ath_softc *sc, int channel)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
|
|
|
@ -167,8 +167,6 @@ static void ath_cancel_work(struct ath_softc *sc)
|
|||
|
||||
static void ath_restart_work(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
|
||||
ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
|
||||
|
||||
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)
|
|||
msecs_to_jiffies(ATH_PLL_WORK_INTERVAL));
|
||||
|
||||
ath_start_rx_poll(sc, 3);
|
||||
|
||||
if (!common->disable_ani)
|
||||
ath_start_ani(common);
|
||||
ath_start_ani(sc);
|
||||
}
|
||||
|
||||
static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
bool ret = true;
|
||||
|
||||
ieee80211_stop_queues(sc->hw);
|
||||
|
||||
sc->hw_busy_count = 0;
|
||||
del_timer_sync(&common->ani.timer);
|
||||
ath_stop_ani(sc);
|
||||
del_timer_sync(&sc->rx_poll_timer);
|
||||
|
||||
ath9k_debug_samp_bb_mac(sc);
|
||||
|
@ -1481,6 +1476,11 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
|
|||
struct ieee80211_bss_conf *bss_conf,
|
||||
u32 changed)
|
||||
{
|
||||
#define CHECK_ANI \
|
||||
(BSS_CHANGED_ASSOC | \
|
||||
BSS_CHANGED_IBSS | \
|
||||
BSS_CHANGED_BEACON_ENABLED)
|
||||
|
||||
struct ath_softc *sc = hw->priv;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
@ -1517,16 +1517,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
|
|||
memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
|
||||
common->curaid = bss_conf->aid;
|
||||
ath9k_hw_write_associd(sc->sc_ah);
|
||||
|
||||
if (bss_conf->ibss_joined) {
|
||||
if (!common->disable_ani) {
|
||||
set_bit(SC_OP_ANI_RUN, &sc->sc_flags);
|
||||
ath_start_ani(common);
|
||||
}
|
||||
} else {
|
||||
clear_bit(SC_OP_ANI_RUN, &sc->sc_flags);
|
||||
del_timer_sync(&common->ani.timer);
|
||||
}
|
||||
}
|
||||
|
||||
if ((changed & BSS_CHANGED_BEACON_ENABLED) ||
|
||||
|
@ -1557,8 +1547,13 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
|
|||
}
|
||||
}
|
||||
|
||||
if (changed & CHECK_ANI)
|
||||
ath_check_ani(sc);
|
||||
|
||||
mutex_unlock(&sc->mutex);
|
||||
ath9k_ps_restore(sc);
|
||||
|
||||
#undef CHECK_ANI
|
||||
}
|
||||
|
||||
static u64 ath9k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
||||
|
|
Loading…
Reference in New Issue