Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b238e90e authored by Sujith's avatar Sujith Committed by John W. Linville
Browse files

ath9k: Handle TSF properly for AP mode



The TSF has to be reset only once, upon bringing
the interface up in AP mode. For any beacon reconfigure calls
after that, resetting the TSF results in incorrect beacon generation.
The only exception is a change in the beacon interval,
which is indicated to the driver by mac80211 through
IEEE80211_CONF_CHANGE_BEACON_INTERVAL, handle this properly.

Signed-off-by: default avatarSujith <Sujith.Manoharan@atheros.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 5379c8a2
Loading
Loading
Loading
Loading
+17 −16
Original line number Diff line number Diff line
@@ -558,6 +558,7 @@ struct ath_rfkill {
#define SC_OP_WAIT_FOR_BEACON   BIT(13)
#define SC_OP_LED_ON            BIT(14)
#define SC_OP_SCANNING          BIT(15)
#define SC_OP_TSF_RESET         BIT(16)

struct ath_bus_ops {
	void		(*read_cachesize)(struct ath_softc *sc, int *csz);
+10 −0
Original line number Diff line number Diff line
@@ -510,6 +510,11 @@ static void ath_beacon_config_ap(struct ath_softc *sc,
{
	u32 nexttbtt, intval;

	/* Configure the timers only when the TSF has to be reset */

	if (!(sc->sc_flags & SC_OP_TSF_RESET))
		return;

	/* NB: the beacon interval is kept internally in TU's */
	intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
	intval /= ATH_BCBUF;    /* for staggered beacons */
@@ -530,6 +535,11 @@ static void ath_beacon_config_ap(struct ath_softc *sc,
	ath9k_hw_beaconinit(sc->sc_ah, nexttbtt, intval);
	sc->beacon.bmisscnt = 0;
	ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);

	/* Clear the reset TSF flag, so that subsequent beacon updation
	   will not reset the HW TSF. */

	sc->sc_flags &= ~SC_OP_TSF_RESET;
}

/*
+13 −1
Original line number Diff line number Diff line
@@ -2168,8 +2168,10 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
	avp->av_opmode = ic_opmode;
	avp->av_bslot = -1;

	if (ic_opmode == NL80211_IFTYPE_AP)
	if (ic_opmode == NL80211_IFTYPE_AP) {
		ath9k_hw_set_tsfadjust(sc->sc_ah, 1);
		sc->sc_flags |= SC_OP_TSF_RESET;
	}

	sc->vifs[0] = conf->vif;
	sc->nvifs++;
@@ -2291,6 +2293,16 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
	if (changed & IEEE80211_CONF_CHANGE_POWER)
		sc->config.txpowlimit = 2 * conf->power_level;

	/*
	 * The HW TSF has to be reset when the beacon interval changes.
	 * We set the flag here, and ath_beacon_config_ap() would take this
	 * into account when it gets called through the subsequent
	 * config_interface() call - with IFCC_BEACON in the changed field.
	 */

	if (changed & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
		sc->sc_flags |= SC_OP_TSF_RESET;

	mutex_unlock(&sc->mutex);

	return 0;