diff options
Diffstat (limited to 'drivers/net/wireless/ath5k/base.c')
-rw-r--r-- | drivers/net/wireless/ath5k/base.c | 68 |
1 files changed, 45 insertions, 23 deletions
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index 0f1d6bdd51a2..2d14255eb103 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c | |||
@@ -240,6 +240,10 @@ static u64 ath5k_get_tsf(struct ieee80211_hw *hw); | |||
240 | static void ath5k_reset_tsf(struct ieee80211_hw *hw); | 240 | static void ath5k_reset_tsf(struct ieee80211_hw *hw); |
241 | static int ath5k_beacon_update(struct ieee80211_hw *hw, | 241 | static int ath5k_beacon_update(struct ieee80211_hw *hw, |
242 | struct sk_buff *skb); | 242 | struct sk_buff *skb); |
243 | static void ath5k_bss_info_changed(struct ieee80211_hw *hw, | ||
244 | struct ieee80211_vif *vif, | ||
245 | struct ieee80211_bss_conf *bss_conf, | ||
246 | u32 changes); | ||
243 | 247 | ||
244 | static struct ieee80211_ops ath5k_hw_ops = { | 248 | static struct ieee80211_ops ath5k_hw_ops = { |
245 | .tx = ath5k_tx, | 249 | .tx = ath5k_tx, |
@@ -256,6 +260,7 @@ static struct ieee80211_ops ath5k_hw_ops = { | |||
256 | .get_tx_stats = ath5k_get_tx_stats, | 260 | .get_tx_stats = ath5k_get_tx_stats, |
257 | .get_tsf = ath5k_get_tsf, | 261 | .get_tsf = ath5k_get_tsf, |
258 | .reset_tsf = ath5k_reset_tsf, | 262 | .reset_tsf = ath5k_reset_tsf, |
263 | .bss_info_changed = ath5k_bss_info_changed, | ||
259 | }; | 264 | }; |
260 | 265 | ||
261 | /* | 266 | /* |
@@ -661,8 +666,7 @@ ath5k_pci_resume(struct pci_dev *pdev) | |||
661 | { | 666 | { |
662 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | 667 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); |
663 | struct ath5k_softc *sc = hw->priv; | 668 | struct ath5k_softc *sc = hw->priv; |
664 | struct ath5k_hw *ah = sc->ah; | 669 | int err; |
665 | int i, err; | ||
666 | 670 | ||
667 | pci_restore_state(pdev); | 671 | pci_restore_state(pdev); |
668 | 672 | ||
@@ -688,16 +692,6 @@ ath5k_pci_resume(struct pci_dev *pdev) | |||
688 | goto err_irq; | 692 | goto err_irq; |
689 | ath5k_led_enable(sc); | 693 | ath5k_led_enable(sc); |
690 | 694 | ||
691 | /* | ||
692 | * Reset the key cache since some parts do not | ||
693 | * reset the contents on initial power up or resume. | ||
694 | * | ||
695 | * FIXME: This may need to be revisited when mac80211 becomes | ||
696 | * aware of suspend/resume. | ||
697 | */ | ||
698 | for (i = 0; i < AR5K_KEYTABLE_SIZE; i++) | ||
699 | ath5k_hw_reset_key(ah, i); | ||
700 | |||
701 | return 0; | 695 | return 0; |
702 | err_irq: | 696 | err_irq: |
703 | free_irq(pdev->irq, sc); | 697 | free_irq(pdev->irq, sc); |
@@ -718,7 +712,6 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) | |||
718 | struct ath5k_softc *sc = hw->priv; | 712 | struct ath5k_softc *sc = hw->priv; |
719 | struct ath5k_hw *ah = sc->ah; | 713 | struct ath5k_hw *ah = sc->ah; |
720 | u8 mac[ETH_ALEN]; | 714 | u8 mac[ETH_ALEN]; |
721 | unsigned int i; | ||
722 | int ret; | 715 | int ret; |
723 | 716 | ||
724 | ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device); | 717 | ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device); |
@@ -737,13 +730,6 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) | |||
737 | __set_bit(ATH_STAT_MRRETRY, sc->status); | 730 | __set_bit(ATH_STAT_MRRETRY, sc->status); |
738 | 731 | ||
739 | /* | 732 | /* |
740 | * Reset the key cache since some parts do not | ||
741 | * reset the contents on initial power up. | ||
742 | */ | ||
743 | for (i = 0; i < AR5K_KEYTABLE_SIZE; i++) | ||
744 | ath5k_hw_reset_key(ah, i); | ||
745 | |||
746 | /* | ||
747 | * Collect the channel list. The 802.11 layer | 733 | * Collect the channel list. The 802.11 layer |
748 | * is resposible for filtering this list based | 734 | * is resposible for filtering this list based |
749 | * on settings like the phy mode and regulatory | 735 | * on settings like the phy mode and regulatory |
@@ -2202,7 +2188,8 @@ ath5k_beacon_config(struct ath5k_softc *sc) | |||
2202 | static int | 2188 | static int |
2203 | ath5k_init(struct ath5k_softc *sc, bool is_resume) | 2189 | ath5k_init(struct ath5k_softc *sc, bool is_resume) |
2204 | { | 2190 | { |
2205 | int ret; | 2191 | struct ath5k_hw *ah = sc->ah; |
2192 | int ret, i; | ||
2206 | 2193 | ||
2207 | mutex_lock(&sc->lock); | 2194 | mutex_lock(&sc->lock); |
2208 | 2195 | ||
@@ -2235,10 +2222,17 @@ ath5k_init(struct ath5k_softc *sc, bool is_resume) | |||
2235 | if (ret) | 2222 | if (ret) |
2236 | goto done; | 2223 | goto done; |
2237 | 2224 | ||
2225 | /* | ||
2226 | * Reset the key cache since some parts do not reset the | ||
2227 | * contents on initial power up or resume from suspend. | ||
2228 | */ | ||
2229 | for (i = 0; i < AR5K_KEYTABLE_SIZE; i++) | ||
2230 | ath5k_hw_reset_key(ah, i); | ||
2231 | |||
2238 | __set_bit(ATH_STAT_STARTED, sc->status); | 2232 | __set_bit(ATH_STAT_STARTED, sc->status); |
2239 | 2233 | ||
2240 | /* Set ack to be sent at low bit-rates */ | 2234 | /* Set ack to be sent at low bit-rates */ |
2241 | ath5k_hw_set_ack_bitrate_high(sc->ah, false); | 2235 | ath5k_hw_set_ack_bitrate_high(ah, false); |
2242 | 2236 | ||
2243 | mod_timer(&sc->calib_tim, round_jiffies(jiffies + | 2237 | mod_timer(&sc->calib_tim, round_jiffies(jiffies + |
2244 | msecs_to_jiffies(ath5k_calinterval * 1000))); | 2238 | msecs_to_jiffies(ath5k_calinterval * 1000))); |
@@ -2953,7 +2947,7 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw, | |||
2953 | sc->opmode != NL80211_IFTYPE_MESH_POINT && | 2947 | sc->opmode != NL80211_IFTYPE_MESH_POINT && |
2954 | test_bit(ATH_STAT_PROMISC, sc->status)) | 2948 | test_bit(ATH_STAT_PROMISC, sc->status)) |
2955 | rfilt |= AR5K_RX_FILTER_PROM; | 2949 | rfilt |= AR5K_RX_FILTER_PROM; |
2956 | if (sc->opmode == NL80211_IFTYPE_STATION || | 2950 | if ((sc->opmode == NL80211_IFTYPE_STATION && sc->assoc) || |
2957 | sc->opmode == NL80211_IFTYPE_ADHOC) { | 2951 | sc->opmode == NL80211_IFTYPE_ADHOC) { |
2958 | rfilt |= AR5K_RX_FILTER_BEACON; | 2952 | rfilt |= AR5K_RX_FILTER_BEACON; |
2959 | } | 2953 | } |
@@ -3094,4 +3088,32 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
3094 | end: | 3088 | end: |
3095 | return ret; | 3089 | return ret; |
3096 | } | 3090 | } |
3091 | static void | ||
3092 | set_beacon_filter(struct ieee80211_hw *hw, bool enable) | ||
3093 | { | ||
3094 | struct ath5k_softc *sc = hw->priv; | ||
3095 | struct ath5k_hw *ah = sc->ah; | ||
3096 | u32 rfilt; | ||
3097 | rfilt = ath5k_hw_get_rx_filter(ah); | ||
3098 | if (enable) | ||
3099 | rfilt |= AR5K_RX_FILTER_BEACON; | ||
3100 | else | ||
3101 | rfilt &= ~AR5K_RX_FILTER_BEACON; | ||
3102 | ath5k_hw_set_rx_filter(ah, rfilt); | ||
3103 | sc->filter_flags = rfilt; | ||
3104 | } | ||
3097 | 3105 | ||
3106 | static void ath5k_bss_info_changed(struct ieee80211_hw *hw, | ||
3107 | struct ieee80211_vif *vif, | ||
3108 | struct ieee80211_bss_conf *bss_conf, | ||
3109 | u32 changes) | ||
3110 | { | ||
3111 | struct ath5k_softc *sc = hw->priv; | ||
3112 | if (changes & BSS_CHANGED_ASSOC) { | ||
3113 | mutex_lock(&sc->lock); | ||
3114 | sc->assoc = bss_conf->assoc; | ||
3115 | if (sc->opmode == NL80211_IFTYPE_STATION) | ||
3116 | set_beacon_filter(hw, sc->assoc); | ||
3117 | mutex_unlock(&sc->lock); | ||
3118 | } | ||
3119 | } | ||