ath9k_hw: make bluetooth coexistence support optional at compile time

Many systems (e.g. embedded systems) do not have wifi modules connected to
bluetooth modules, so bluetooth coexistence is irrelevant there. With the
addition of MCI support, ath9k picked up quite a bit of extra code that
can be compiled out this way.

This patch redefines ATH9K_HW_CAP_MCI and adds an inline wrapper for
querying the bluetooth coexistence scheme, allowing the compiler to
eliminate code that uses it, with only very little use of #ifdef.

On MIPS this reduces the total size for the modules by about 20k.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index 1b4786a..dc6be4a 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -81,6 +81,14 @@
 	  Say Y, if you want to use the ath9k specific rate control
 	  module instead of minstrel_ht.
 
+config ATH9K_BTCOEX_SUPPORT
+	bool "Atheros ath9k bluetooth coexistence support"
+	depends on ATH9K
+	default y
+	---help---
+	  Say Y, if you want to use the ath9k radios together with
+	  Bluetooth modules in the same system.
+
 config ATH9K_HTC
        tristate "Atheros HTC based wireless cards support"
        depends on USB && MAC80211
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c
index fdd0f81..709520c 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c
@@ -85,6 +85,9 @@
 {
 	u32 payload[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffff00};
 
+	if (!ATH9K_HW_CAP_MCI)
+		return;
+
 	ar9003_mci_send_message(ah, MCI_REMOTE_RESET, 0, payload, 16,
 				wait_done, false);
 	udelay(5);
@@ -94,6 +97,9 @@
 {
 	u32 payload = 0x00000000;
 
+	if (!ATH9K_HW_CAP_MCI)
+		return;
+
 	ar9003_mci_send_message(ah, MCI_LNA_TRANS, 0, &payload, 1,
 				wait_done, false);
 }
@@ -107,6 +113,9 @@
 
 void ar9003_mci_send_sys_waking(struct ath_hw *ah, bool wait_done)
 {
+	if (!ATH9K_HW_CAP_MCI)
+		return;
+
 	ar9003_mci_send_message(ah, MCI_SYS_WAKING, MCI_FLAG_DISABLE_TIMESTAMP,
 				NULL, 0, wait_done, false);
 }
@@ -220,6 +229,9 @@
 	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
 	u32 payload[4] = {0, 0, 0, 0};
 
+	if (!ATH9K_HW_CAP_MCI)
+		return;
+
 	ath_dbg(common, MCI, "MCI Send Coex %s BT GPM\n",
 		(halt) ? "halt" : "unhalt");
 
@@ -374,12 +386,17 @@
 
 void ar9003_mci_disable_interrupt(struct ath_hw *ah)
 {
+	if (!ATH9K_HW_CAP_MCI)
+		return;
+
 	REG_WRITE(ah, AR_MCI_INTERRUPT_EN, 0);
 	REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, 0);
 }
 
 void ar9003_mci_enable_interrupt(struct ath_hw *ah)
 {
+	if (!ATH9K_HW_CAP_MCI)
+		return;
 
 	REG_WRITE(ah, AR_MCI_INTERRUPT_EN, AR_MCI_INTERRUPT_DEFAULT);
 	REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN,
@@ -390,6 +407,9 @@
 {
 	u32 intr;
 
+	if (!ATH9K_HW_CAP_MCI)
+		return false;
+
 	intr = REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW);
 	return ((intr & ints) == ints);
 }
@@ -398,6 +418,10 @@
 			      u32 *rx_msg_intr)
 {
 	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
+
+	if (!ATH9K_HW_CAP_MCI)
+		return;
+
 	*raw_intr = mci->raw_intr;
 	*rx_msg_intr = mci->rx_msg_intr;
 
@@ -411,6 +435,9 @@
 {
 	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
 
+	if (!ATH9K_HW_CAP_MCI)
+		return;
+
 	if (!mci->update_2g5g &&
 	    (mci->is_2g != is_2g))
 		mci->update_2g5g = true;
@@ -524,6 +551,9 @@
 	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
 	u32 regval, thresh;
 
+	if (!ATH9K_HW_CAP_MCI)
+		return;
+
 	ath_dbg(common, MCI, "MCI full_sleep = %d, is_2g = %d\n",
 		is_full_sleep, is_2g);
 
@@ -650,6 +680,9 @@
 {
 	struct ath_common *common = ath9k_hw_common(ah);
 
+	if (!ATH9K_HW_CAP_MCI)
+		return;
+
 	/* disable all MCI messages */
 	REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, 0xffff0000);
 	REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS0, 0xffffffff);
@@ -682,6 +715,9 @@
 	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
 	u32 cur_bt_state;
 
+	if (!ATH9K_HW_CAP_MCI)
+		return;
+
 	cur_bt_state = ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL);
 
 	if (mci->bt_state != cur_bt_state) {
@@ -844,6 +880,9 @@
 	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
 
+	if (!ATH9K_HW_CAP_MCI)
+		return;
+
 	if (mci->update_2g5g) {
 		if (mci->is_2g) {
 
@@ -895,6 +934,9 @@
 	u32 saved_mci_int_en;
 	int i;
 
+	if (!ATH9K_HW_CAP_MCI)
+		return false;
+
 	saved_mci_int_en = REG_READ(ah, AR_MCI_INTERRUPT_EN);
 	regval = REG_READ(ah, AR_BTCOEX_CTRL);
 
@@ -961,6 +1003,9 @@
 	struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
 	void *sched_buf = (void *)((char *) gpm_buf + (sched_addr - gpm_addr));
 
+	if (!ATH9K_HW_CAP_MCI)
+		return;
+
 	mci->gpm_addr = gpm_addr;
 	mci->gpm_buf = gpm_buf;
 	mci->gpm_len = len;
@@ -975,6 +1020,9 @@
 {
 	struct ath_common *common = ath9k_hw_common(ah);
 
+	if (!ATH9K_HW_CAP_MCI)
+		return;
+
 	/* Turn off MCI and Jupiter mode. */
 	REG_WRITE(ah, AR_BTCOEX_CTRL, 0x00);
 	ath_dbg(common, MCI, "MCI ar9003_mci_cleanup\n");
@@ -1039,6 +1087,9 @@
 	u8 recv_type = 0, recv_opcode = 0;
 	bool b_is_bt_cal_done = (gpm_type == MCI_GPM_BT_CAL_DONE);
 
+	if (!ATH9K_HW_CAP_MCI)
+		return 0;
+
 	more_data = time_out ? MCI_GPM_NOMORE : MCI_GPM_MORE;
 
 	while (time_out > 0) {
@@ -1168,6 +1219,9 @@
 	u32 value = 0, more_gpm = 0, gpm_ptr;
 	u8 query_type;
 
+	if (!ATH9K_HW_CAP_MCI)
+		return 0;
+
 	switch (state_type) {
 	case MCI_STATE_ENABLE:
 		if (mci->ready) {
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index 553d279..a6712a9 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -68,6 +68,9 @@
 	u32 i, idx;
 	bool rxclear_polarity = ath_bt_config.bt_rxclear_polarity;
 
+	if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
+		return;
+
 	if (AR_SREV_9300_20_OR_LATER(ah))
 		rxclear_polarity = !ath_bt_config.bt_rxclear_polarity;
 
@@ -99,6 +102,9 @@
 {
 	struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
 
+	if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
+		return;
+
 	/* connect bt_active to baseband */
 	REG_CLR_BIT(ah, AR_GPIO_INPUT_EN_VAL,
 		    (AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF |
@@ -121,6 +127,9 @@
 {
 	struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
 
+	if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
+		return;
+
 	/* btcoex 3-wire */
 	REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
 			(AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB |
@@ -147,6 +156,9 @@
 {
 	struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
 
+	if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
+		return;
+
 	/* Configure the desired GPIO port for TX_FRAME output */
 	ath9k_hw_cfg_output(ah, btcoex_hw->wlanactive_gpio,
 			    AR_GPIO_OUTPUT_MUX_AS_TX_FRAME);
@@ -158,6 +170,9 @@
 {
 	struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
 
+	if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
+		return;
+
 	btcoex_hw->bt_coex_weights = SM(bt_weight, AR_BTCOEX_BT_WGHT) |
 				     SM(wlan_weight, AR_BTCOEX_WL_WGHT);
 }
@@ -219,9 +234,9 @@
 {
 	struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
 
-	switch (btcoex_hw->scheme) {
+	switch (ath9k_hw_get_btcoex_scheme(ah)) {
 	case ATH_BTCOEX_CFG_NONE:
-		break;
+		return;
 	case ATH_BTCOEX_CFG_2WIRE:
 		ath9k_hw_btcoex_enable_2wire(ah);
 		break;
@@ -246,6 +261,9 @@
 	struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
 	int i;
 
+	if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
+		return;
+
 	btcoex_hw->enabled = false;
 	if (btcoex_hw->scheme == ATH_BTCOEX_CFG_MCI) {
 		ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE);
@@ -294,6 +312,9 @@
 void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah,
 			      enum ath_stomp_type stomp_type)
 {
+	if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
+		return;
+
 	if (AR_SREV_9300_20_OR_LATER(ah)) {
 		ar9003_btcoex_bt_stomp(ah, stomp_type);
 		return;
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index 7834d70..597c84e 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -249,6 +249,9 @@
 {
 	struct ath_btcoex *btcoex = &sc->btcoex;
 
+	if (ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_NONE)
+		return 0;
+
 	btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000;
 	btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
 		btcoex->btcoex_period / 100;
@@ -281,6 +284,9 @@
 
 	ath_dbg(ath9k_hw_common(ah), BTCOEX, "Starting btcoex timers\n");
 
+	if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
+		return;
+
 	/* make sure duty cycle timer is also stopped when resuming */
 	if (btcoex->hw_timer_enabled)
 		ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer);
@@ -301,6 +307,9 @@
 	struct ath_btcoex *btcoex = &sc->btcoex;
 	struct ath_hw *ah = sc->sc_ah;
 
+	if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
+		return;
+
 	del_timer_sync(&btcoex->period_timer);
 
 	if (btcoex->hw_timer_enabled)
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
index b7c03001..6506e1f 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
@@ -115,6 +115,9 @@
 {
 	struct ath_btcoex *btcoex = &priv->btcoex;
 
+	if (ath9k_hw_get_btcoex_scheme(priv->ah) == ATH_BTCOEX_CFG_NONE)
+		return;
+
 	btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD;
 	btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
 		btcoex->btcoex_period / 100;
@@ -133,6 +136,9 @@
 	struct ath_btcoex *btcoex = &priv->btcoex;
 	struct ath_hw *ah = priv->ah;
 
+	if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
+		return;
+
 	ath_dbg(ath9k_hw_common(ah), BTCOEX, "Starting btcoex work\n");
 
 	btcoex->bt_priority_cnt = 0;
@@ -147,6 +153,9 @@
  */
 void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv)
 {
+	if (ath9k_hw_get_btcoex_scheme(priv->ah) == ATH_BTCOEX_CFG_NONE)
+		return;
+
 	cancel_delayed_work_sync(&priv->coex_period_work);
 	cancel_delayed_work_sync(&priv->duty_cycle_work);
 }
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index 6cbad73..9be10a2 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -607,7 +607,7 @@
 {
 	int qnum;
 
-	switch (priv->ah->btcoex_hw.scheme) {
+	switch (ath9k_hw_get_btcoex_scheme(priv->ah)) {
 	case ATH_BTCOEX_CFG_NONE:
 		break;
 	case ATH_BTCOEX_CFG_3WIRE:
@@ -701,7 +701,8 @@
 
 	if (product && strncmp(product, ATH_HTC_BTCOEX_PRODUCT_ID, 5) == 0) {
 		ah->btcoex_hw.scheme = ATH_BTCOEX_CFG_3WIRE;
-		ath9k_init_btcoex(priv);
+		if (ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE)
+			ath9k_init_btcoex(priv);
 	}
 
 	return 0;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 539f445..ef4c606 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -957,7 +957,7 @@
 	mod_timer(&priv->tx.cleanup_timer,
 		  jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));
 
-	if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) {
+	if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) {
 		ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
 					   AR_STOMP_LOW_WLAN_WGHT);
 		ath9k_hw_btcoex_enable(ah);
@@ -1009,7 +1009,8 @@
 
 	mutex_lock(&priv->mutex);
 
-	if (ah->btcoex_hw.enabled) {
+	if (ah->btcoex_hw.enabled &&
+	    ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) {
 		ath9k_hw_btcoex_disable(ah);
 		if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
 			ath_htc_cancel_btcoex_work(priv);
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 0fde031..ee77595 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1891,7 +1891,8 @@
 #endif
 	}
 
-	if (ah->btcoex_hw.enabled)
+	if (ah->btcoex_hw.enabled &&
+	    ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE)
 		ath9k_hw_btcoex_enable(ah);
 
 	if (mci && mci_hw->ready) {
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 615cc83..48205c2 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -209,7 +209,11 @@
 	ATH9K_HW_CAP_5GHZ			= BIT(12),
 	ATH9K_HW_CAP_APM			= BIT(13),
 	ATH9K_HW_CAP_RTT			= BIT(14),
+#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
 	ATH9K_HW_CAP_MCI			= BIT(15),
+#else
+	ATH9K_HW_CAP_MCI			= 0,
+#endif
 	ATH9K_HW_CAP_DFS			= BIT(16),
 };
 
@@ -1228,6 +1232,16 @@
 void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr,
 			      u32 *rx_msg_intr);
 
+#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
+static inline enum ath_btcoex_scheme
+ath9k_hw_get_btcoex_scheme(struct ath_hw *ah)
+{
+	return ah->btcoex_hw.scheme;
+}
+#else
+#define ath9k_hw_get_btcoex_scheme(...) ATH_BTCOEX_CFG_NONE
+#endif
+
 #define ATH9K_CLOCK_RATE_CCK		22
 #define ATH9K_CLOCK_RATE_5GHZ_OFDM	40
 #define ATH9K_CLOCK_RATE_2GHZ_OFDM	44
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 58ce67f..abf9435 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -425,7 +425,7 @@
 	struct ath_hw *ah = sc->sc_ah;
 	int r;
 
-	switch (sc->sc_ah->btcoex_hw.scheme) {
+	switch (ath9k_hw_get_btcoex_scheme(sc->sc_ah)) {
 	case ATH_BTCOEX_CFG_NONE:
 		break;
 	case ATH_BTCOEX_CFG_2WIRE:
@@ -880,10 +880,10 @@
 		kfree(sc->sbands[IEEE80211_BAND_5GHZ].channels);
 
         if ((sc->btcoex.no_stomp_timer) &&
-	    sc->sc_ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
+	    ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_3WIRE)
 		ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer);
 
-	if (sc->sc_ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_MCI)
+	if (ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_MCI)
 		ath_mci_cleanup(sc);
 
 	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index eb06e4f..6e3d838 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -741,11 +741,11 @@
 			ath_tx_tasklet(sc);
 	}
 
-	if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
+	if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE)
 		if (status & ATH9K_INT_GENTIMER)
 			ath_gen_timer_isr(sc->sc_ah);
 
-	if (status & ATH9K_INT_MCI)
+	if ((status & ATH9K_INT_MCI) && ATH9K_HW_CAP_MCI)
 		ath_mci_intr(sc);
 
 out:
@@ -1081,14 +1081,14 @@
 
 	spin_unlock_bh(&sc->sc_pcu_lock);
 
-	if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) &&
+	if ((ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) &&
 	    !ah->btcoex_hw.enabled) {
 		if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI))
 			ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
 						   AR_STOMP_LOW_WLAN_WGHT);
 		ath9k_hw_btcoex_enable(ah);
 
-		if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
+		if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE)
 			ath9k_btcoex_timer_resume(sc);
 	}
 
@@ -1191,9 +1191,10 @@
 	/* Ensure HW is awake when we try to shut it down. */
 	ath9k_ps_wakeup(sc);
 
-	if (ah->btcoex_hw.enabled) {
+	if (ah->btcoex_hw.enabled &&
+	    ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) {
 		ath9k_hw_btcoex_disable(ah);
-		if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
+		if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE)
 			ath9k_btcoex_timer_pause(sc);
 		ath_mci_flush_profile(&sc->btcoex.mci);
 	}
diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c
index ca9b53c..fee8c6f 100644
--- a/drivers/net/wireless/ath/ath9k/mci.c
+++ b/drivers/net/wireless/ath/ath9k/mci.c
@@ -417,6 +417,9 @@
 	struct ath_mci_coex *mci = &sc->mci_coex;
 	int error = 0;
 
+	if (!ATH9K_HW_CAP_MCI)
+		return 0;
+
 	mci->sched_buf.bf_len = ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE;
 
 	if (ath_mci_buf_alloc(sc, &mci->sched_buf)) {
@@ -450,6 +453,9 @@
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath_mci_coex *mci = &sc->mci_coex;
 
+	if (!ATH9K_HW_CAP_MCI)
+		return;
+
 	/*
 	 * both schedule and gpm buffers will be released
 	 */
@@ -468,6 +474,9 @@
 	u32 more_data = MCI_GPM_MORE;
 	bool skip_gpm = false;
 
+	if (!ATH9K_HW_CAP_MCI)
+		return;
+
 	ar9003_mci_get_interrupt(sc->sc_ah, &mci_int, &mci_int_rxmsg);
 
 	if (ar9003_mci_state(ah, MCI_STATE_ENABLE, NULL) == 0) {
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index a439edc..77dc327 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -121,7 +121,7 @@
 	if (!parent)
 		return;
 
-	if (ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) {
+	if (ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) {
 		/* Bluetooth coexistance requires disabling ASPM. */
 		pci_read_config_byte(pdev, pos + PCI_EXP_LNKCTL, &aspm);
 		aspm &= ~(PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1);