void ath_scan_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_startrecv(struct ath_softc *sc);
bool ath_stoprecv(struct ath_softc *sc);
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 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);
/**********/
struct completion paprd_complete;
wait_queue_head_t tx_wait;
+#ifdef CONFIG_ATH9K_CHANNEL_CONTEXT
struct ath_gen_timer *p2p_ps_timer;
struct ath_vif *p2p_ps_vif;
+#endif
unsigned long driver_data;
{
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);
+#endif
tsf_time -= ath9k_hw_gettsf32(ah);
tsf_time = msecs_to_jiffies(tsf_time / 1000) + 1;
mod_timer(&sc->sched.timer, tsf_time);
}
}
-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;
s32 tsf, target_tsf;
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)
{
struct ath_softc *sc = priv;
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;
- u32 tsf;
+ spin_lock_bh(&sc->sc_pcu_lock);
+ 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);
+}
+
+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;
+ return -ENOMEM;
- if (vif->type != NL80211_IFTYPE_STATION || !vif->p2p)
- return;
+ return 0;
+}
- 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_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 */
if (ret)
goto err_btcoex;
- 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)
+ ret = ath9k_init_p2p(sc);
+ if (ret)
goto err_btcoex;
ath9k_cmn_init_crypto(sc->sc_ah);
{
int i = 0;
- if (sc->p2p_ps_timer)
- ath_gen_timer_free(sc->sc_ah, sc->p2p_ps_timer);
-
+ ath9k_deinit_p2p(sc);
ath9k_deinit_btcoex(sc);
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
mutex_lock(&sc->mutex);
- spin_lock_bh(&sc->sc_pcu_lock);
- 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);
+ ath9k_p2p_remove_vif(sc, vif);
sc->nvifs--;
sc->tx99_vif = NULL;
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
struct ath_vif *avp = (void *)vif->drv_priv;
- unsigned long flags;
int slottime;
ath9k_ps_wakeup(sc);
}
}
- if (changed & BSS_CHANGED_P2P_PS) {
- 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);
- }
+ if (changed & BSS_CHANGED_P2P_PS)
+ ath9k_p2p_bss_info_changed(sc, vif);
if (changed & CHECK_ANI)
ath_check_ani(sc);
"Reconfigure beacon timers based on synchronized timestamp\n");
if (!(WARN_ON_ONCE(sc->cur_chan->beacon.beacon_interval == 0)))
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)) {