aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/beacon.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/beacon.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c44
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
749static 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
749void ath_set_beacon(struct ath_softc *sc) 768void 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)
774void ath9k_set_beaconing_status(struct ath_softc *sc, bool status) 800void 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);