diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/beacon.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/beacon.c | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index eccb0ec87adb..24f565ba9988 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -320,6 +320,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp) | |||
320 | if (avp->av_bcbuf != NULL) { | 320 | if (avp->av_bcbuf != NULL) { |
321 | struct ath_buf *bf; | 321 | struct ath_buf *bf; |
322 | 322 | ||
323 | avp->is_bslot_active = false; | ||
323 | if (avp->av_bslot != -1) { | 324 | if (avp->av_bslot != -1) { |
324 | sc->beacon.bslot[avp->av_bslot] = NULL; | 325 | sc->beacon.bslot[avp->av_bslot] = NULL; |
325 | sc->nbcnvifs--; | 326 | sc->nbcnvifs--; |
@@ -743,9 +744,27 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
743 | cur_conf->dtim_period = 1; | 744 | cur_conf->dtim_period = 1; |
744 | 745 | ||
745 | ath_set_beacon(sc); | 746 | ath_set_beacon(sc); |
746 | sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; | ||
747 | } | 747 | } |
748 | 748 | ||
749 | static bool ath_has_valid_bslot(struct ath_softc *sc) | ||
750 | { | ||
751 | struct ath_vif *avp; | ||
752 | int slot; | ||
753 | bool found = false; | ||
754 | |||
755 | for (slot = 0; slot < ATH_BCBUF; slot++) { | ||
756 | if (sc->beacon.bslot[slot]) { | ||
757 | avp = (void *)sc->beacon.bslot[slot]->drv_priv; | ||
758 | if (avp->is_bslot_active) { | ||
759 | found = true; | ||
760 | break; | ||
761 | } | ||
762 | } | ||
763 | } | ||
764 | return found; | ||
765 | } | ||
766 | |||
767 | |||
749 | void ath_set_beacon(struct ath_softc *sc) | 768 | void ath_set_beacon(struct ath_softc *sc) |
750 | { | 769 | { |
751 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 770 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
@@ -753,7 +772,8 @@ void ath_set_beacon(struct ath_softc *sc) | |||
753 | 772 | ||
754 | switch (sc->sc_ah->opmode) { | 773 | switch (sc->sc_ah->opmode) { |
755 | case NL80211_IFTYPE_AP: | 774 | case NL80211_IFTYPE_AP: |
756 | ath_beacon_config_ap(sc, cur_conf); | 775 | if (ath_has_valid_bslot(sc)) |
776 | ath_beacon_config_ap(sc, cur_conf); | ||
757 | break; | 777 | break; |
758 | case NL80211_IFTYPE_ADHOC: | 778 | case NL80211_IFTYPE_ADHOC: |
759 | case NL80211_IFTYPE_MESH_POINT: | 779 | case NL80211_IFTYPE_MESH_POINT: |
@@ -761,6 +781,12 @@ void ath_set_beacon(struct ath_softc *sc) | |||
761 | break; | 781 | break; |
762 | case NL80211_IFTYPE_STATION: | 782 | case NL80211_IFTYPE_STATION: |
763 | ath_beacon_config_sta(sc, cur_conf); | 783 | ath_beacon_config_sta(sc, cur_conf); |
784 | /* | ||
785 | * Request a re-configuration of Beacon related timers | ||
786 | * on the receipt of the first Beacon frame (i.e., | ||
787 | * after time sync with the AP). | ||
788 | */ | ||
789 | sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; | ||
764 | break; | 790 | break; |
765 | default: | 791 | default: |
766 | ath_dbg(common, ATH_DBG_CONFIG, | 792 | ath_dbg(common, ATH_DBG_CONFIG, |
@@ -774,20 +800,8 @@ void ath_set_beacon(struct ath_softc *sc) | |||
774 | void ath9k_set_beaconing_status(struct ath_softc *sc, bool status) | 800 | void ath9k_set_beaconing_status(struct ath_softc *sc, bool status) |
775 | { | 801 | { |
776 | struct ath_hw *ah = sc->sc_ah; | 802 | struct ath_hw *ah = sc->sc_ah; |
777 | struct ath_vif *avp; | ||
778 | int slot; | ||
779 | bool found = false; | ||
780 | 803 | ||
781 | for (slot = 0; slot < ATH_BCBUF; slot++) { | 804 | if (!ath_has_valid_bslot(sc)) |
782 | if (sc->beacon.bslot[slot]) { | ||
783 | avp = (void *)sc->beacon.bslot[slot]->drv_priv; | ||
784 | if (avp->is_bslot_active) { | ||
785 | found = true; | ||
786 | break; | ||
787 | } | ||
788 | } | ||
789 | } | ||
790 | if (!found) | ||
791 | return; | 805 | return; |
792 | 806 | ||
793 | ath9k_ps_wakeup(sc); | 807 | ath9k_ps_wakeup(sc); |