diff options
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/mci.c | 50 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/mci.h | 23 |
3 files changed, 78 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 2da62be081f7..515e184ab47f 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1450,6 +1450,9 @@ static void ath9k_set_assoc_state(struct ath_softc *sc, sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; spin_unlock_irqrestore(&sc->sc_pm_lock, flags); + if (ath9k_hw_mci_is_enabled(sc->sc_ah)) + ath9k_mci_update_wlan_channels(sc, false); + ath_dbg(common, CONFIG, "Primary Station interface: %pM, BSSID: %pM\n", vif->addr, common->curbssid); @@ -1506,6 +1509,8 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, memset(common->curbssid, 0, ETH_ALEN); common->curaid = 0; ath9k_hw_write_associd(sc->sc_ah); + if (ath9k_hw_mci_is_enabled(sc->sc_ah)) + ath9k_mci_update_wlan_channels(sc, true); } } diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index ec2d7c807567..1733a5ac3279 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c @@ -600,3 +600,53 @@ void ath_mci_enable(struct ath_softc *sc) if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI) sc->sc_ah->imask |= ATH9K_INT_MCI; } + +void ath9k_mci_update_wlan_channels(struct ath_softc *sc, bool allow_all) +{ + struct ath_hw *ah = sc->sc_ah; + struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; + struct ath9k_channel *chan = ah->curchan; + u32 channelmap[] = {0x00000000, 0xffff0000, 0xffffffff, 0x7fffffff}; + int i; + s16 chan_start, chan_end; + u16 wlan_chan; + + if (!chan || !IS_CHAN_2GHZ(chan)) + return; + + if (allow_all) + goto send_wlan_chan; + + wlan_chan = chan->channel - 2402; + + chan_start = wlan_chan - 10; + chan_end = wlan_chan + 10; + + if (chan->chanmode == CHANNEL_G_HT40PLUS) + chan_end += 20; + else if (chan->chanmode == CHANNEL_G_HT40MINUS) + chan_start -= 20; + + /* adjust side band */ + chan_start -= 7; + chan_end += 7; + + if (chan_start <= 0) + chan_start = 0; + if (chan_end >= ATH_MCI_NUM_BT_CHANNELS) + chan_end = ATH_MCI_NUM_BT_CHANNELS - 1; + + ath_dbg(ath9k_hw_common(ah), MCI, + "WLAN current channel %d mask BT channel %d - %d\n", + wlan_chan, chan_start, chan_end); + + for (i = chan_start; i < chan_end; i++) + MCI_GPM_CLR_CHANNEL_BIT(&channelmap, i); + +send_wlan_chan: + /* update and send wlan channels info to BT */ + for (i = 0; i < 4; i++) + mci->wlan_channels[i] = channelmap[i]; + ar9003_mci_send_wlan_channels(ah); + ar9003_mci_state(ah, MCI_STATE_SEND_VERSION_QUERY); +} diff --git a/drivers/net/wireless/ath/ath9k/mci.h b/drivers/net/wireless/ath/ath9k/mci.h index fc14eea034eb..a3df314c1e70 100644 --- a/drivers/net/wireless/ath/ath9k/mci.h +++ b/drivers/net/wireless/ath/ath9k/mci.h @@ -32,6 +32,24 @@ #define ATH_MCI_MAX_PROFILE (ATH_MCI_MAX_ACL_PROFILE +\ ATH_MCI_MAX_SCO_PROFILE) +#define ATH_MCI_NUM_BT_CHANNELS 79 + +#define MCI_GPM_SET_CHANNEL_BIT(_p_gpm, _bt_chan) \ + do { \ + if (_bt_chan < ATH_MCI_NUM_BT_CHANNELS) { \ + *(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_CHANNEL_MAP + \ + (_bt_chan / 8)) |= (1 << (_bt_chan & 7)); \ + } \ + } while (0) + +#define MCI_GPM_CLR_CHANNEL_BIT(_p_gpm, _bt_chan) \ + do { \ + if (_bt_chan < ATH_MCI_NUM_BT_CHANNELS) { \ + *(((u8 *)(_p_gpm)) + MCI_GPM_COEX_B_CHANNEL_MAP + \ + (_bt_chan / 8)) &= ~(1 << (_bt_chan & 7));\ + } \ + } while (0) + #define INC_PROF(_mci, _info) do { \ switch (_info->type) { \ case MCI_GPM_COEX_PROFILE_RFCOMM:\ @@ -133,10 +151,15 @@ void ath_mci_intr(struct ath_softc *sc); #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT void ath_mci_enable(struct ath_softc *sc); +void ath9k_mci_update_wlan_channels(struct ath_softc *sc, bool allow_all); #else static inline void ath_mci_enable(struct ath_softc *sc) { } +static inline void ath9k_mci_update_wlan_channels(struct ath_softc *sc, + bool allow_all) +{ +} #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ #endif /* MCI_H*/ |