aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorRajkumar Manoharan <rmanoharan@atheros.com>2010-10-27 09:01:15 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-11-08 16:53:46 -0500
commit5f841b4130a639e5f0fbcf4a9b26045d734e4ee6 (patch)
tree2a13d6467b753647a779cb47f2cb97d440f4d2b8 /drivers/net/wireless
parent269e2d77b82d92d8dad543a2375e74372e9d773e (diff)
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: Rajkumar Manoharan <rmanoharan@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c14
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c12
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c4
4 files changed, 23 insertions, 8 deletions
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index cc13ee117823..c3a49045986d 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -952,9 +952,12 @@ static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)
952 REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION); 952 REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
953 break; 953 break;
954 case NL80211_IFTYPE_STATION: 954 case NL80211_IFTYPE_STATION:
955 case NL80211_IFTYPE_MONITOR:
956 REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE); 955 REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
957 break; 956 break;
957 default:
958 if (ah->is_monitoring)
959 REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
960 break;
958 } 961 }
959} 962}
960 963
@@ -1634,7 +1637,6 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
1634 1637
1635 switch (ah->opmode) { 1638 switch (ah->opmode) {
1636 case NL80211_IFTYPE_STATION: 1639 case NL80211_IFTYPE_STATION:
1637 case NL80211_IFTYPE_MONITOR:
1638 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon)); 1640 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
1639 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff); 1641 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
1640 REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff); 1642 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 AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN; 1665 AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
1664 break; 1666 break;
1665 default: 1667 default:
1668 if (ah->is_monitoring) {
1669 REG_WRITE(ah, AR_NEXT_TBTT_TIMER,
1670 TU_TO_USEC(next_beacon));
1671 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
1672 REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
1673 flags |= AR_TBTT_TIMER_EN;
1674 break;
1675 }
1666 ath_print(ath9k_hw_common(ah), ATH_DBG_BEACON, 1676 ath_print(ath9k_hw_common(ah), ATH_DBG_BEACON,
1667 "%s: unsupported opmode: %d\n", 1677 "%s: unsupported opmode: %d\n",
1668 __func__, ah->opmode); 1678 __func__, ah->opmode);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index d032939768b0..d47d1b4b6002 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -622,6 +622,7 @@ struct ath_hw {
622 622
623 bool sw_mgmt_crypto; 623 bool sw_mgmt_crypto;
624 bool is_pciexpress; 624 bool is_pciexpress;
625 bool is_monitoring;
625 bool need_an_top2_fixup; 626 bool need_an_top2_fixup;
626 u16 tx_trig_level; 627 u16 tx_trig_level;
627 628
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index b52f1cf8a603..cf6fa54a2fa3 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1217,6 +1217,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
1217 ah->imask |= ATH9K_INT_CST; 1217 ah->imask |= ATH9K_INT_CST;
1218 1218
1219 sc->sc_flags &= ~SC_OP_INVALID; 1219 sc->sc_flags &= ~SC_OP_INVALID;
1220 sc->sc_ah->is_monitoring = false;
1220 1221
1221 /* Disable BMISS interrupt when we're not associated */ 1222 /* Disable BMISS interrupt when we're not associated */
1222 ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); 1223 ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
@@ -1493,8 +1494,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
1493 ath9k_hw_set_interrupts(ah, ah->imask); 1494 ath9k_hw_set_interrupts(ah, ah->imask);
1494 1495
1495 if (vif->type == NL80211_IFTYPE_AP || 1496 if (vif->type == NL80211_IFTYPE_AP ||
1496 vif->type == NL80211_IFTYPE_ADHOC || 1497 vif->type == NL80211_IFTYPE_ADHOC) {
1497 vif->type == NL80211_IFTYPE_MONITOR) {
1498 sc->sc_flags |= SC_OP_ANI_RUN; 1498 sc->sc_flags |= SC_OP_ANI_RUN;
1499 ath_start_ani(common); 1499 ath_start_ani(common);
1500 } 1500 }
@@ -1644,8 +1644,12 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1644 if (changed & IEEE80211_CONF_CHANGE_MONITOR) { 1644 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
1645 if (conf->flags & IEEE80211_CONF_MONITOR) { 1645 if (conf->flags & IEEE80211_CONF_MONITOR) {
1646 ath_print(common, ATH_DBG_CONFIG, 1646 ath_print(common, ATH_DBG_CONFIG,
1647 "HW opmode set to Monitor mode\n"); 1647 "Monitor mode is enabled\n");
1648 sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR; 1648 sc->sc_ah->is_monitoring = true;
1649 } else {
1650 ath_print(common, ATH_DBG_CONFIG,
1651 "Monitor mode is disabled\n");
1652 sc->sc_ah->is_monitoring = false;
1649 } 1653 }
1650 } 1654 }
1651 1655
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index fddb0129bb57..c76ea53c20ce 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -441,7 +441,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
441 */ 441 */
442 if (((sc->sc_ah->opmode != NL80211_IFTYPE_AP) && 442 if (((sc->sc_ah->opmode != NL80211_IFTYPE_AP) &&
443 (sc->rx.rxfilter & FIF_PROMISC_IN_BSS)) || 443 (sc->rx.rxfilter & FIF_PROMISC_IN_BSS)) ||
444 (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR)) 444 (sc->sc_ah->is_monitoring))
445 rfilt |= ATH9K_RX_FILTER_PROM; 445 rfilt |= ATH9K_RX_FILTER_PROM;
446 446
447 if (sc->rx.rxfilter & FIF_CONTROL) 447 if (sc->rx.rxfilter & FIF_CONTROL)
@@ -897,7 +897,7 @@ static bool ath9k_rx_accept(struct ath_common *common,
897 * decryption and MIC failures. For monitor mode, 897 * decryption and MIC failures. For monitor mode,
898 * we also ignore the CRC error. 898 * we also ignore the CRC error.
899 */ 899 */
900 if (ah->opmode == NL80211_IFTYPE_MONITOR) { 900 if (ah->is_monitoring) {
901 if (rx_stats->rs_status & 901 if (rx_stats->rs_status &
902 ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC | 902 ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
903 ATH9K_RXERR_CRC)) 903 ATH9K_RXERR_CRC))