ath9k: Isolate P2P powersave routines

Use CONFIG_ATH9K_CHANNEL_CONTEXT to conditionally
compile P2P-PS code.

Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Sujith Manoharan 2014-08-22 20:39:30 +05:30 committed by John W. Linville
parent 2471adff1f
commit c7dd40c92a
5 changed files with 114 additions and 39 deletions

View File

@ -436,6 +436,39 @@ void ath_offchannel_next(struct ath_softc *sc);
void ath_scan_complete(struct ath_softc *sc, bool abort); void ath_scan_complete(struct ath_softc *sc, bool abort);
void ath_roc_complete(struct ath_softc *sc, bool abort); void ath_roc_complete(struct ath_softc *sc, bool abort);
#ifdef CONFIG_ATH9K_CHANNEL_CONTEXT
int ath9k_init_p2p(struct ath_softc *sc);
void ath9k_deinit_p2p(struct ath_softc *sc);
void ath9k_p2p_remove_vif(struct ath_softc *sc,
struct ieee80211_vif *vif);
void ath9k_p2p_beacon_sync(struct ath_softc *sc);
void ath9k_p2p_bss_info_changed(struct ath_softc *sc,
struct ieee80211_vif *vif);
void ath9k_p2p_ps_timer(void *priv);
#else
static inline int ath9k_init_p2p(struct ath_softc *sc)
{
return 0;
}
static inline void ath9k_deinit_p2p(struct ath_softc *sc)
{
}
static inline void ath9k_p2p_remove_vif(struct ath_softc *sc,
struct ieee80211_vif *vif)
{
}
static inline void ath9k_p2p_beacon_sync(struct ath_softc *sc)
{
}
static inline void ath9k_p2p_bss_info_changed(struct ath_softc *sc,
struct ieee80211_vif *vif)
{
}
static inline void ath9k_p2p_ps_timer(struct ath_softc *sc)
{
}
#endif /* CONFIG_ATH9K_CHANNEL_CONTEXT */
int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan); int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan);
int ath_startrecv(struct ath_softc *sc); int ath_startrecv(struct ath_softc *sc);
bool ath_stoprecv(struct ath_softc *sc); bool ath_stoprecv(struct ath_softc *sc);
@ -600,9 +633,6 @@ int ath_update_survey_stats(struct ath_softc *sc);
void ath_update_survey_nf(struct ath_softc *sc, int channel); void ath_update_survey_nf(struct ath_softc *sc, int channel);
void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type); void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type);
void ath_ps_full_sleep(unsigned long data); void ath_ps_full_sleep(unsigned long data);
void ath9k_p2p_ps_timer(void *priv);
void ath9k_update_p2p_ps_timer(struct ath_softc *sc, struct ath_vif *avp);
void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif);
void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop); void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop);
/**********/ /**********/
@ -857,8 +887,10 @@ struct ath_softc {
struct completion paprd_complete; struct completion paprd_complete;
wait_queue_head_t tx_wait; wait_queue_head_t tx_wait;
#ifdef CONFIG_ATH9K_CHANNEL_CONTEXT
struct ath_gen_timer *p2p_ps_timer; struct ath_gen_timer *p2p_ps_timer;
struct ath_vif *p2p_ps_vif; struct ath_vif *p2p_ps_vif;
#endif
unsigned long driver_data; unsigned long driver_data;

View File

@ -514,7 +514,9 @@ static void ath_chanctx_setup_timer(struct ath_softc *sc, u32 tsf_time)
{ {
struct ath_hw *ah = sc->sc_ah; struct ath_hw *ah = sc->sc_ah;
#ifdef CONFIG_ATH9K_CHANNEL_CONTEXT
ath9k_hw_gen_timer_start(ah, sc->p2p_ps_timer, tsf_time, 1000000); ath9k_hw_gen_timer_start(ah, sc->p2p_ps_timer, tsf_time, 1000000);
#endif
tsf_time -= ath9k_hw_gettsf32(ah); tsf_time -= ath9k_hw_gettsf32(ah);
tsf_time = msecs_to_jiffies(tsf_time / 1000) + 1; tsf_time = msecs_to_jiffies(tsf_time / 1000) + 1;
mod_timer(&sc->sched.timer, tsf_time); mod_timer(&sc->sched.timer, tsf_time);
@ -945,7 +947,13 @@ void ath_offchannel_timer(unsigned long data)
} }
} }
void ath9k_update_p2p_ps_timer(struct ath_softc *sc, struct ath_vif *avp) #ifdef CONFIG_ATH9K_CHANNEL_CONTEXT
/*****************/
/* P2P Powersave */
/*****************/
static void ath9k_update_p2p_ps_timer(struct ath_softc *sc, struct ath_vif *avp)
{ {
struct ath_hw *ah = sc->sc_ah; struct ath_hw *ah = sc->sc_ah;
s32 tsf, target_tsf; s32 tsf, target_tsf;
@ -967,6 +975,23 @@ void ath9k_update_p2p_ps_timer(struct ath_softc *sc, struct ath_vif *avp)
ath9k_hw_gen_timer_start(ah, sc->p2p_ps_timer, (u32) target_tsf, 1000000); ath9k_hw_gen_timer_start(ah, sc->p2p_ps_timer, (u32) target_tsf, 1000000);
} }
static void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif)
{
struct ath_vif *avp = (void *)vif->drv_priv;
u32 tsf;
if (!sc->p2p_ps_timer)
return;
if (vif->type != NL80211_IFTYPE_STATION || !vif->p2p)
return;
sc->p2p_ps_vif = avp;
tsf = ath9k_hw_gettsf32(sc->sc_ah);
ieee80211_parse_p2p_noa(&vif->bss_conf.p2p_noa_attr, &avp->noa, tsf);
ath9k_update_p2p_ps_timer(sc, avp);
}
void ath9k_p2p_ps_timer(void *priv) void ath9k_p2p_ps_timer(void *priv)
{ {
struct ath_softc *sc = priv; struct ath_softc *sc = priv;
@ -1014,19 +1039,52 @@ void ath9k_p2p_ps_timer(void *priv)
rcu_read_unlock(); rcu_read_unlock();
} }
void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif) void ath9k_p2p_bss_info_changed(struct ath_softc *sc,
struct ieee80211_vif *vif)
{
unsigned long flags;
spin_lock_bh(&sc->sc_pcu_lock);
spin_lock_irqsave(&sc->sc_pm_lock, flags);
if (!(sc->ps_flags & PS_BEACON_SYNC))
ath9k_update_p2p_ps(sc, vif);
spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
spin_unlock_bh(&sc->sc_pcu_lock);
}
void ath9k_p2p_beacon_sync(struct ath_softc *sc)
{
if (sc->p2p_ps_vif)
ath9k_update_p2p_ps(sc, sc->p2p_ps_vif->vif);
}
void ath9k_p2p_remove_vif(struct ath_softc *sc,
struct ieee80211_vif *vif)
{ {
struct ath_vif *avp = (void *)vif->drv_priv; struct ath_vif *avp = (void *)vif->drv_priv;
u32 tsf;
if (!sc->p2p_ps_timer) spin_lock_bh(&sc->sc_pcu_lock);
return; if (avp == sc->p2p_ps_vif) {
sc->p2p_ps_vif = NULL;
if (vif->type != NL80211_IFTYPE_STATION || !vif->p2p) ath9k_update_p2p_ps_timer(sc, NULL);
return; }
spin_unlock_bh(&sc->sc_pcu_lock);
sc->p2p_ps_vif = avp;
tsf = ath9k_hw_gettsf32(sc->sc_ah);
ieee80211_parse_p2p_noa(&vif->bss_conf.p2p_noa_attr, &avp->noa, tsf);
ath9k_update_p2p_ps_timer(sc, avp);
} }
int ath9k_init_p2p(struct ath_softc *sc)
{
sc->p2p_ps_timer = ath_gen_timer_alloc(sc->sc_ah, ath9k_p2p_ps_timer,
NULL, sc, AR_FIRST_NDP_TIMER);
if (!sc->p2p_ps_timer)
return -ENOMEM;
return 0;
}
void ath9k_deinit_p2p(struct ath_softc *sc)
{
if (sc->p2p_ps_timer)
ath_gen_timer_free(sc->sc_ah, sc->p2p_ps_timer);
}
#endif /* CONFIG_ATH9K_CHANNEL_CONTEXT */

View File

@ -600,9 +600,8 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
if (ret) if (ret)
goto err_btcoex; goto err_btcoex;
sc->p2p_ps_timer = ath_gen_timer_alloc(sc->sc_ah, ath9k_p2p_ps_timer, ret = ath9k_init_p2p(sc);
NULL, sc, AR_FIRST_NDP_TIMER); if (ret)
if (!sc->p2p_ps_timer)
goto err_btcoex; goto err_btcoex;
ath9k_cmn_init_crypto(sc->sc_ah); ath9k_cmn_init_crypto(sc->sc_ah);
@ -919,9 +918,7 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
{ {
int i = 0; int i = 0;
if (sc->p2p_ps_timer) ath9k_deinit_p2p(sc);
ath_gen_timer_free(sc->sc_ah, sc->p2p_ps_timer);
ath9k_deinit_btcoex(sc); ath9k_deinit_btcoex(sc);
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)

View File

@ -1213,12 +1213,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
mutex_lock(&sc->mutex); mutex_lock(&sc->mutex);
spin_lock_bh(&sc->sc_pcu_lock); ath9k_p2p_remove_vif(sc, vif);
if (avp == sc->p2p_ps_vif) {
sc->p2p_ps_vif = NULL;
ath9k_update_p2p_ps_timer(sc, NULL);
}
spin_unlock_bh(&sc->sc_pcu_lock);
sc->nvifs--; sc->nvifs--;
sc->tx99_vif = NULL; sc->tx99_vif = NULL;
@ -1678,7 +1673,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
struct ath_hw *ah = sc->sc_ah; struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
struct ath_vif *avp = (void *)vif->drv_priv; struct ath_vif *avp = (void *)vif->drv_priv;
unsigned long flags;
int slottime; int slottime;
ath9k_ps_wakeup(sc); ath9k_ps_wakeup(sc);
@ -1727,14 +1721,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
} }
} }
if (changed & BSS_CHANGED_P2P_PS) { if (changed & BSS_CHANGED_P2P_PS)
spin_lock_bh(&sc->sc_pcu_lock); ath9k_p2p_bss_info_changed(sc, vif);
spin_lock_irqsave(&sc->sc_pm_lock, flags);
if (!(sc->ps_flags & PS_BEACON_SYNC))
ath9k_update_p2p_ps(sc, vif);
spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
spin_unlock_bh(&sc->sc_pcu_lock);
}
if (changed & CHECK_ANI) if (changed & CHECK_ANI)
ath_check_ani(sc); ath_check_ani(sc);

View File

@ -547,8 +547,8 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
"Reconfigure beacon timers based on synchronized timestamp\n"); "Reconfigure beacon timers based on synchronized timestamp\n");
if (!(WARN_ON_ONCE(sc->cur_chan->beacon.beacon_interval == 0))) if (!(WARN_ON_ONCE(sc->cur_chan->beacon.beacon_interval == 0)))
ath9k_set_beacon(sc); ath9k_set_beacon(sc);
if (sc->p2p_ps_vif)
ath9k_update_p2p_ps(sc, sc->p2p_ps_vif->vif); ath9k_p2p_beacon_sync(sc);
} }
if (ath_beacon_dtim_pending_cab(skb)) { if (ath_beacon_dtim_pending_cab(skb)) {