Commit 5f841b41 authored by Rajkumar Manoharan's avatar Rajkumar Manoharan Committed by John W. Linville

ath9k: Avoid HW opmode overridden on monitor mode changes

The HW opmode is blindly set to monitor type on monitor mode
change notification. This overrides the opmode when one of the
interfaces is still running as non-monitor iftype. So the monitoring
information needs to be maintained seperately.
Signed-off-by: default avatarRajkumar Manoharan <rmanoharan@atheros.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 269e2d77
...@@ -952,9 +952,12 @@ static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode) ...@@ -952,9 +952,12 @@ static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)
REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
break; break;
case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_MONITOR:
REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE); REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
break; break;
default:
if (ah->is_monitoring)
REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
break;
} }
} }
...@@ -1634,7 +1637,6 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period) ...@@ -1634,7 +1637,6 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
switch (ah->opmode) { switch (ah->opmode) {
case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_MONITOR:
REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon)); REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff); REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff); REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
...@@ -1663,6 +1665,14 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period) ...@@ -1663,6 +1665,14 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN; AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
break; break;
default: default:
if (ah->is_monitoring) {
REG_WRITE(ah, AR_NEXT_TBTT_TIMER,
TU_TO_USEC(next_beacon));
REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
flags |= AR_TBTT_TIMER_EN;
break;
}
ath_print(ath9k_hw_common(ah), ATH_DBG_BEACON, ath_print(ath9k_hw_common(ah), ATH_DBG_BEACON,
"%s: unsupported opmode: %d\n", "%s: unsupported opmode: %d\n",
__func__, ah->opmode); __func__, ah->opmode);
......
...@@ -622,6 +622,7 @@ struct ath_hw { ...@@ -622,6 +622,7 @@ struct ath_hw {
bool sw_mgmt_crypto; bool sw_mgmt_crypto;
bool is_pciexpress; bool is_pciexpress;
bool is_monitoring;
bool need_an_top2_fixup; bool need_an_top2_fixup;
u16 tx_trig_level; u16 tx_trig_level;
......
...@@ -1217,6 +1217,7 @@ static int ath9k_start(struct ieee80211_hw *hw) ...@@ -1217,6 +1217,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
ah->imask |= ATH9K_INT_CST; ah->imask |= ATH9K_INT_CST;
sc->sc_flags &= ~SC_OP_INVALID; sc->sc_flags &= ~SC_OP_INVALID;
sc->sc_ah->is_monitoring = false;
/* Disable BMISS interrupt when we're not associated */ /* Disable BMISS interrupt when we're not associated */
ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
...@@ -1493,8 +1494,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, ...@@ -1493,8 +1494,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
ath9k_hw_set_interrupts(ah, ah->imask); ath9k_hw_set_interrupts(ah, ah->imask);
if (vif->type == NL80211_IFTYPE_AP || if (vif->type == NL80211_IFTYPE_AP ||
vif->type == NL80211_IFTYPE_ADHOC || vif->type == NL80211_IFTYPE_ADHOC) {
vif->type == NL80211_IFTYPE_MONITOR) {
sc->sc_flags |= SC_OP_ANI_RUN; sc->sc_flags |= SC_OP_ANI_RUN;
ath_start_ani(common); ath_start_ani(common);
} }
...@@ -1644,8 +1644,12 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) ...@@ -1644,8 +1644,12 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
if (changed & IEEE80211_CONF_CHANGE_MONITOR) { if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
if (conf->flags & IEEE80211_CONF_MONITOR) { if (conf->flags & IEEE80211_CONF_MONITOR) {
ath_print(common, ATH_DBG_CONFIG, ath_print(common, ATH_DBG_CONFIG,
"HW opmode set to Monitor mode\n"); "Monitor mode is enabled\n");
sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR; sc->sc_ah->is_monitoring = true;
} else {
ath_print(common, ATH_DBG_CONFIG,
"Monitor mode is disabled\n");
sc->sc_ah->is_monitoring = false;
} }
} }
......
...@@ -441,7 +441,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc) ...@@ -441,7 +441,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
*/ */
if (((sc->sc_ah->opmode != NL80211_IFTYPE_AP) && if (((sc->sc_ah->opmode != NL80211_IFTYPE_AP) &&
(sc->rx.rxfilter & FIF_PROMISC_IN_BSS)) || (sc->rx.rxfilter & FIF_PROMISC_IN_BSS)) ||
(sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR)) (sc->sc_ah->is_monitoring))
rfilt |= ATH9K_RX_FILTER_PROM; rfilt |= ATH9K_RX_FILTER_PROM;
if (sc->rx.rxfilter & FIF_CONTROL) if (sc->rx.rxfilter & FIF_CONTROL)
...@@ -897,7 +897,7 @@ static bool ath9k_rx_accept(struct ath_common *common, ...@@ -897,7 +897,7 @@ static bool ath9k_rx_accept(struct ath_common *common,
* decryption and MIC failures. For monitor mode, * decryption and MIC failures. For monitor mode,
* we also ignore the CRC error. * we also ignore the CRC error.
*/ */
if (ah->opmode == NL80211_IFTYPE_MONITOR) { if (ah->is_monitoring) {
if (rx_stats->rs_status & if (rx_stats->rs_status &
~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC | ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
ATH9K_RXERR_CRC)) ATH9K_RXERR_CRC))
......
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