Commit 50072ebc authored by Rajkumar Manoharan's avatar Rajkumar Manoharan Committed by John W. Linville
Browse files

ath9k: Send WLAN channel info to BT



WLAN updates channel bitmap when associated and disassociated. Channel
bitmap will reflect whare are the channels used or affected by WLAN and
BT should avoid using those. Not doing so, could affect BT traffic
as both WLAN and BT is operating on same channel.
Signed-off-by: default avatarRajkumar Manoharan <rmanohar@qca.qualcomm.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent aebc0d40
......@@ -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);
}
}
......
......@@ -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);
}
......@@ -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*/
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment