#define SC_OP_WAIT_FOR_PSPOLL_DATA BIT(17)
#define SC_OP_WAIT_FOR_TX_ACK BIT(18)
#define SC_OP_BEACON_SYNC BIT(19)
+#define SC_OP_BTCOEX_ENABLED BIT(20)
struct ath_bus_ops {
void (*read_cachesize)(struct ath_softc *sc, int *csz);
/* Bluetooth Coexistence */
/***************************/
-void ath9k_hw_btcoex_enable(struct ath_hw *ah)
+void ath9k_hw_btcoex_init(struct ath_hw *ah)
{
/* connect bt_active to baseband */
REG_CLR_BIT(ah, AR_GPIO_INPUT_EN_VAL,
/* Configure the desired gpio port for input */
ath9k_hw_cfg_gpio_input(ah, ah->btactive_gpio);
+}
+void ath9k_hw_btcoex_enable(struct ath_hw *ah)
+{
/* Configure the desired GPIO port for TX_FRAME output */
ath9k_hw_cfg_output(ah, ah->wlanactive_gpio,
AR_GPIO_OUTPUT_MUX_AS_TX_FRAME);
+
+ ah->ah_sc->sc_flags |= SC_OP_BTCOEX_ENABLED;
+}
+
+void ath9k_hw_btcoex_disable(struct ath_hw *ah)
+{
+ ath9k_hw_set_gpio(ah, ah->wlanactive_gpio, 0);
+
+ ath9k_hw_cfg_output(ah, ah->wlanactive_gpio,
+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+
+ ah->ah_sc->sc_flags &= ~SC_OP_BTCOEX_ENABLED;
}
bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked);
enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints);
+void ath9k_hw_btcoex_init(struct ath_hw *ah);
void ath9k_hw_btcoex_enable(struct ath_hw *ah);
+void ath9k_hw_btcoex_disable(struct ath_hw *ah);
#endif
ARRAY_SIZE(ath9k_5ghz_chantable);
}
- if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BT_COEX)
- ath9k_hw_btcoex_enable(sc->sc_ah);
+ if (ah->caps.hw_caps & ATH9K_HW_CAP_BT_COEX)
+ ath9k_hw_btcoex_init(ah);
return 0;
bad2:
ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
+ if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BT_COEX) &&
+ !(sc->sc_flags & SC_OP_BTCOEX_ENABLED))
+ ath9k_hw_btcoex_enable(sc->sc_ah);
+
mutex_unlock:
mutex_unlock(&sc->mutex);
wiphy_rfkill_stop_polling(sc->hw->wiphy);
+ if (sc->sc_flags & SC_OP_BTCOEX_ENABLED)
+ ath9k_hw_btcoex_disable(sc->sc_ah);
+
/* disable HAL and put h/w to sleep */
ath9k_hw_disable(sc->sc_ah);
ath9k_hw_configpcipowersave(sc->sc_ah, 1);