dect
/
linux-2.6
Archived
13
0
Fork 0

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: Rajkumar Manoharan <rmanohar@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Rajkumar Manoharan 2012-10-12 14:07:22 +05:30 committed by John W. Linville
parent aebc0d40f9
commit 50072ebca3
3 changed files with 78 additions and 0 deletions

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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*/