diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath5k/base.c')
-rw-r--r-- | drivers/net/wireless/ath/ath5k/base.c | 67 |
1 files changed, 33 insertions, 34 deletions
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index cc6d41dec332..9d37c1a43a9d 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -195,7 +195,7 @@ static const struct ieee80211_rate ath5k_rates[] = { | |||
195 | static int __devinit ath5k_pci_probe(struct pci_dev *pdev, | 195 | static int __devinit ath5k_pci_probe(struct pci_dev *pdev, |
196 | const struct pci_device_id *id); | 196 | const struct pci_device_id *id); |
197 | static void __devexit ath5k_pci_remove(struct pci_dev *pdev); | 197 | static void __devexit ath5k_pci_remove(struct pci_dev *pdev); |
198 | #ifdef CONFIG_PM | 198 | #ifdef CONFIG_PM_SLEEP |
199 | static int ath5k_pci_suspend(struct device *dev); | 199 | static int ath5k_pci_suspend(struct device *dev); |
200 | static int ath5k_pci_resume(struct device *dev); | 200 | static int ath5k_pci_resume(struct device *dev); |
201 | 201 | ||
@@ -203,7 +203,7 @@ static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume); | |||
203 | #define ATH5K_PM_OPS (&ath5k_pm_ops) | 203 | #define ATH5K_PM_OPS (&ath5k_pm_ops) |
204 | #else | 204 | #else |
205 | #define ATH5K_PM_OPS NULL | 205 | #define ATH5K_PM_OPS NULL |
206 | #endif /* CONFIG_PM */ | 206 | #endif /* CONFIG_PM_SLEEP */ |
207 | 207 | ||
208 | static struct pci_driver ath5k_pci_driver = { | 208 | static struct pci_driver ath5k_pci_driver = { |
209 | .name = KBUILD_MODNAME, | 209 | .name = KBUILD_MODNAME, |
@@ -222,7 +222,6 @@ static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb); | |||
222 | static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, | 222 | static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, |
223 | struct ath5k_txq *txq); | 223 | struct ath5k_txq *txq); |
224 | static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan); | 224 | static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan); |
225 | static int ath5k_reset_wake(struct ath5k_softc *sc); | ||
226 | static int ath5k_start(struct ieee80211_hw *hw); | 225 | static int ath5k_start(struct ieee80211_hw *hw); |
227 | static void ath5k_stop(struct ieee80211_hw *hw); | 226 | static void ath5k_stop(struct ieee80211_hw *hw); |
228 | static int ath5k_add_interface(struct ieee80211_hw *hw, | 227 | static int ath5k_add_interface(struct ieee80211_hw *hw, |
@@ -579,7 +578,7 @@ ath5k_pci_probe(struct pci_dev *pdev, | |||
579 | spin_lock_init(&sc->block); | 578 | spin_lock_init(&sc->block); |
580 | 579 | ||
581 | /* Set private data */ | 580 | /* Set private data */ |
582 | pci_set_drvdata(pdev, hw); | 581 | pci_set_drvdata(pdev, sc); |
583 | 582 | ||
584 | /* Setup interrupt handler */ | 583 | /* Setup interrupt handler */ |
585 | ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc); | 584 | ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc); |
@@ -695,25 +694,23 @@ err: | |||
695 | static void __devexit | 694 | static void __devexit |
696 | ath5k_pci_remove(struct pci_dev *pdev) | 695 | ath5k_pci_remove(struct pci_dev *pdev) |
697 | { | 696 | { |
698 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | 697 | struct ath5k_softc *sc = pci_get_drvdata(pdev); |
699 | struct ath5k_softc *sc = hw->priv; | ||
700 | 698 | ||
701 | ath5k_debug_finish_device(sc); | 699 | ath5k_debug_finish_device(sc); |
702 | ath5k_detach(pdev, hw); | 700 | ath5k_detach(pdev, sc->hw); |
703 | ath5k_hw_detach(sc->ah); | 701 | ath5k_hw_detach(sc->ah); |
704 | kfree(sc->ah); | 702 | kfree(sc->ah); |
705 | free_irq(pdev->irq, sc); | 703 | free_irq(pdev->irq, sc); |
706 | pci_iounmap(pdev, sc->iobase); | 704 | pci_iounmap(pdev, sc->iobase); |
707 | pci_release_region(pdev, 0); | 705 | pci_release_region(pdev, 0); |
708 | pci_disable_device(pdev); | 706 | pci_disable_device(pdev); |
709 | ieee80211_free_hw(hw); | 707 | ieee80211_free_hw(sc->hw); |
710 | } | 708 | } |
711 | 709 | ||
712 | #ifdef CONFIG_PM | 710 | #ifdef CONFIG_PM_SLEEP |
713 | static int ath5k_pci_suspend(struct device *dev) | 711 | static int ath5k_pci_suspend(struct device *dev) |
714 | { | 712 | { |
715 | struct ieee80211_hw *hw = pci_get_drvdata(to_pci_dev(dev)); | 713 | struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev)); |
716 | struct ath5k_softc *sc = hw->priv; | ||
717 | 714 | ||
718 | ath5k_led_off(sc); | 715 | ath5k_led_off(sc); |
719 | return 0; | 716 | return 0; |
@@ -722,8 +719,7 @@ static int ath5k_pci_suspend(struct device *dev) | |||
722 | static int ath5k_pci_resume(struct device *dev) | 719 | static int ath5k_pci_resume(struct device *dev) |
723 | { | 720 | { |
724 | struct pci_dev *pdev = to_pci_dev(dev); | 721 | struct pci_dev *pdev = to_pci_dev(dev); |
725 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | 722 | struct ath5k_softc *sc = pci_get_drvdata(pdev); |
726 | struct ath5k_softc *sc = hw->priv; | ||
727 | 723 | ||
728 | /* | 724 | /* |
729 | * Suspend/Resume resets the PCI configuration space, so we have to | 725 | * Suspend/Resume resets the PCI configuration space, so we have to |
@@ -735,7 +731,7 @@ static int ath5k_pci_resume(struct device *dev) | |||
735 | ath5k_led_enable(sc); | 731 | ath5k_led_enable(sc); |
736 | return 0; | 732 | return 0; |
737 | } | 733 | } |
738 | #endif /* CONFIG_PM */ | 734 | #endif /* CONFIG_PM_SLEEP */ |
739 | 735 | ||
740 | 736 | ||
741 | /***********************\ | 737 | /***********************\ |
@@ -865,6 +861,8 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) | |||
865 | 861 | ||
866 | ath5k_init_leds(sc); | 862 | ath5k_init_leds(sc); |
867 | 863 | ||
864 | ath5k_sysfs_register(sc); | ||
865 | |||
868 | return 0; | 866 | return 0; |
869 | err_queues: | 867 | err_queues: |
870 | ath5k_txq_release(sc); | 868 | ath5k_txq_release(sc); |
@@ -900,6 +898,7 @@ ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw) | |||
900 | ath5k_hw_release_tx_queue(sc->ah, sc->bhalq); | 898 | ath5k_hw_release_tx_queue(sc->ah, sc->bhalq); |
901 | ath5k_unregister_leds(sc); | 899 | ath5k_unregister_leds(sc); |
902 | 900 | ||
901 | ath5k_sysfs_unregister(sc); | ||
903 | /* | 902 | /* |
904 | * NB: can't reclaim these until after ieee80211_ifdetach | 903 | * NB: can't reclaim these until after ieee80211_ifdetach |
905 | * returns because we'll get called back to reclaim node | 904 | * returns because we'll get called back to reclaim node |
@@ -2770,7 +2769,7 @@ ath5k_tasklet_reset(unsigned long data) | |||
2770 | { | 2769 | { |
2771 | struct ath5k_softc *sc = (void *)data; | 2770 | struct ath5k_softc *sc = (void *)data; |
2772 | 2771 | ||
2773 | ath5k_reset_wake(sc); | 2772 | ath5k_reset(sc, sc->curchan); |
2774 | } | 2773 | } |
2775 | 2774 | ||
2776 | /* | 2775 | /* |
@@ -2786,10 +2785,6 @@ ath5k_tasklet_calibrate(unsigned long data) | |||
2786 | /* Only full calibration for now */ | 2785 | /* Only full calibration for now */ |
2787 | ah->ah_cal_mask |= AR5K_CALIBRATION_FULL; | 2786 | ah->ah_cal_mask |= AR5K_CALIBRATION_FULL; |
2788 | 2787 | ||
2789 | /* Stop queues so that calibration | ||
2790 | * doesn't interfere with tx */ | ||
2791 | ieee80211_stop_queues(sc->hw); | ||
2792 | |||
2793 | ATH5K_DBG(sc, ATH5K_DEBUG_CALIBRATE, "channel %u/%x\n", | 2788 | ATH5K_DBG(sc, ATH5K_DEBUG_CALIBRATE, "channel %u/%x\n", |
2794 | ieee80211_frequency_to_channel(sc->curchan->center_freq), | 2789 | ieee80211_frequency_to_channel(sc->curchan->center_freq), |
2795 | sc->curchan->hw_value); | 2790 | sc->curchan->hw_value); |
@@ -2807,8 +2802,16 @@ ath5k_tasklet_calibrate(unsigned long data) | |||
2807 | ieee80211_frequency_to_channel( | 2802 | ieee80211_frequency_to_channel( |
2808 | sc->curchan->center_freq)); | 2803 | sc->curchan->center_freq)); |
2809 | 2804 | ||
2810 | /* Wake queues */ | 2805 | /* Noise floor calibration interrupts rx/tx path while I/Q calibration |
2811 | ieee80211_wake_queues(sc->hw); | 2806 | * doesn't. We stop the queues so that calibration doesn't interfere |
2807 | * with TX and don't run it as often */ | ||
2808 | if (time_is_before_eq_jiffies(ah->ah_cal_next_nf)) { | ||
2809 | ah->ah_cal_next_nf = jiffies + | ||
2810 | msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_NF); | ||
2811 | ieee80211_stop_queues(sc->hw); | ||
2812 | ath5k_hw_update_noise_floor(ah); | ||
2813 | ieee80211_wake_queues(sc->hw); | ||
2814 | } | ||
2812 | 2815 | ||
2813 | ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL; | 2816 | ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL; |
2814 | } | 2817 | } |
@@ -2927,6 +2930,10 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan) | |||
2927 | 2930 | ||
2928 | ath5k_ani_init(ah, ah->ah_sc->ani_state.ani_mode); | 2931 | ath5k_ani_init(ah, ah->ah_sc->ani_state.ani_mode); |
2929 | 2932 | ||
2933 | ah->ah_cal_next_full = jiffies; | ||
2934 | ah->ah_cal_next_ani = jiffies; | ||
2935 | ah->ah_cal_next_nf = jiffies; | ||
2936 | |||
2930 | /* | 2937 | /* |
2931 | * Change channels and update the h/w rate map if we're switching; | 2938 | * Change channels and update the h/w rate map if we're switching; |
2932 | * e.g. 11a to 11b/g. | 2939 | * e.g. 11a to 11b/g. |
@@ -2941,23 +2948,13 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan) | |||
2941 | ath5k_beacon_config(sc); | 2948 | ath5k_beacon_config(sc); |
2942 | /* intrs are enabled by ath5k_beacon_config */ | 2949 | /* intrs are enabled by ath5k_beacon_config */ |
2943 | 2950 | ||
2951 | ieee80211_wake_queues(sc->hw); | ||
2952 | |||
2944 | return 0; | 2953 | return 0; |
2945 | err: | 2954 | err: |
2946 | return ret; | 2955 | return ret; |
2947 | } | 2956 | } |
2948 | 2957 | ||
2949 | static int | ||
2950 | ath5k_reset_wake(struct ath5k_softc *sc) | ||
2951 | { | ||
2952 | int ret; | ||
2953 | |||
2954 | ret = ath5k_reset(sc, sc->curchan); | ||
2955 | if (!ret) | ||
2956 | ieee80211_wake_queues(sc->hw); | ||
2957 | |||
2958 | return ret; | ||
2959 | } | ||
2960 | |||
2961 | static int ath5k_start(struct ieee80211_hw *hw) | 2958 | static int ath5k_start(struct ieee80211_hw *hw) |
2962 | { | 2959 | { |
2963 | return ath5k_init(hw->priv); | 2960 | return ath5k_init(hw->priv); |
@@ -3151,13 +3148,15 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw, | |||
3151 | 3148 | ||
3152 | if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { | 3149 | if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { |
3153 | if (*new_flags & FIF_PROMISC_IN_BSS) { | 3150 | if (*new_flags & FIF_PROMISC_IN_BSS) { |
3154 | rfilt |= AR5K_RX_FILTER_PROM; | ||
3155 | __set_bit(ATH_STAT_PROMISC, sc->status); | 3151 | __set_bit(ATH_STAT_PROMISC, sc->status); |
3156 | } else { | 3152 | } else { |
3157 | __clear_bit(ATH_STAT_PROMISC, sc->status); | 3153 | __clear_bit(ATH_STAT_PROMISC, sc->status); |
3158 | } | 3154 | } |
3159 | } | 3155 | } |
3160 | 3156 | ||
3157 | if (test_bit(ATH_STAT_PROMISC, sc->status)) | ||
3158 | rfilt |= AR5K_RX_FILTER_PROM; | ||
3159 | |||
3161 | /* Note, AR5K_RX_FILTER_MCAST is already enabled */ | 3160 | /* Note, AR5K_RX_FILTER_MCAST is already enabled */ |
3162 | if (*new_flags & FIF_ALLMULTI) { | 3161 | if (*new_flags & FIF_ALLMULTI) { |
3163 | mfilt[0] = ~0; | 3162 | mfilt[0] = ~0; |