Commit 02969b38 authored by Martin Xu's avatar Martin Xu Committed by John W. Linville

ath5k: disable beacon filter when station is not associated

Ath5k driver has too many interrupts per second at idle
http://bugzilla.kernel.org/show_bug.cgi?id=11749Signed-off-by: default avatarMartin Xu <martin.xu@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 33ab625f
...@@ -240,6 +240,10 @@ static u64 ath5k_get_tsf(struct ieee80211_hw *hw); ...@@ -240,6 +240,10 @@ static u64 ath5k_get_tsf(struct ieee80211_hw *hw);
static void ath5k_reset_tsf(struct ieee80211_hw *hw); static void ath5k_reset_tsf(struct ieee80211_hw *hw);
static int ath5k_beacon_update(struct ieee80211_hw *hw, static int ath5k_beacon_update(struct ieee80211_hw *hw,
struct sk_buff *skb); struct sk_buff *skb);
static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf,
u32 changes);
static struct ieee80211_ops ath5k_hw_ops = { static struct ieee80211_ops ath5k_hw_ops = {
.tx = ath5k_tx, .tx = ath5k_tx,
...@@ -256,6 +260,7 @@ static struct ieee80211_ops ath5k_hw_ops = { ...@@ -256,6 +260,7 @@ static struct ieee80211_ops ath5k_hw_ops = {
.get_tx_stats = ath5k_get_tx_stats, .get_tx_stats = ath5k_get_tx_stats,
.get_tsf = ath5k_get_tsf, .get_tsf = ath5k_get_tsf,
.reset_tsf = ath5k_reset_tsf, .reset_tsf = ath5k_reset_tsf,
.bss_info_changed = ath5k_bss_info_changed,
}; };
/* /*
...@@ -2942,7 +2947,7 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw, ...@@ -2942,7 +2947,7 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
sc->opmode != NL80211_IFTYPE_MESH_POINT && sc->opmode != NL80211_IFTYPE_MESH_POINT &&
test_bit(ATH_STAT_PROMISC, sc->status)) test_bit(ATH_STAT_PROMISC, sc->status))
rfilt |= AR5K_RX_FILTER_PROM; rfilt |= AR5K_RX_FILTER_PROM;
if (sc->opmode == NL80211_IFTYPE_STATION || if ((sc->opmode == NL80211_IFTYPE_STATION && sc->assoc) ||
sc->opmode == NL80211_IFTYPE_ADHOC) { sc->opmode == NL80211_IFTYPE_ADHOC) {
rfilt |= AR5K_RX_FILTER_BEACON; rfilt |= AR5K_RX_FILTER_BEACON;
} }
...@@ -3083,4 +3088,32 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) ...@@ -3083,4 +3088,32 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
end: end:
return ret; return ret;
} }
static void
set_beacon_filter(struct ieee80211_hw *hw, bool enable)
{
struct ath5k_softc *sc = hw->priv;
struct ath5k_hw *ah = sc->ah;
u32 rfilt;
rfilt = ath5k_hw_get_rx_filter(ah);
if (enable)
rfilt |= AR5K_RX_FILTER_BEACON;
else
rfilt &= ~AR5K_RX_FILTER_BEACON;
ath5k_hw_set_rx_filter(ah, rfilt);
sc->filter_flags = rfilt;
}
static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf,
u32 changes)
{
struct ath5k_softc *sc = hw->priv;
if (changes & BSS_CHANGED_ASSOC) {
mutex_lock(&sc->lock);
sc->assoc = bss_conf->assoc;
if (sc->opmode == NL80211_IFTYPE_STATION)
set_beacon_filter(hw, sc->assoc);
mutex_unlock(&sc->lock);
}
}
...@@ -179,6 +179,7 @@ struct ath5k_softc { ...@@ -179,6 +179,7 @@ struct ath5k_softc {
struct timer_list calib_tim; /* calibration timer */ struct timer_list calib_tim; /* calibration timer */
int power_level; /* Requested tx power in dbm */ int power_level; /* Requested tx power in dbm */
bool assoc; /* assocate state */
}; };
#define ath5k_hw_hasbssidmask(_ah) \ #define ath5k_hw_hasbssidmask(_ah) \
......
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