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

Commit 64839170 authored by Luis R. Rodriguez's avatar Luis R. Rodriguez Committed by John W. Linville
Browse files

ath9k: disable radio when all devices are marked idle



This uses the new configuration changes indicated up by
mac80211 when all interfaces are marked idle. We need to do
a little more work as we have our own set of virtual
wiphys within ath9k.

Only when all virtual wiphys are inactive do we allow an idle
state change for a wiphy to trigger disabling the radio.

Signed-off-by: default avatarLuis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 709ade9e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -691,6 +691,7 @@ void ath9k_wiphy_pause_all_forced(struct ath_softc *sc,
				  struct ath_wiphy *selected);
bool ath9k_wiphy_scanning(struct ath_softc *sc);
void ath9k_wiphy_work(struct work_struct *work);
bool ath9k_all_wiphys_idle(struct ath_softc *sc);

void ath9k_iowrite32(struct ath_hw *ah, u32 reg_offset, u32 val);
unsigned int ath9k_ioread32(struct ath_hw *ah, u32 reg_offset);
+24 −0
Original line number Diff line number Diff line
@@ -2260,9 +2260,28 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
	struct ath_softc *sc = aphy->sc;
	struct ieee80211_conf *conf = &hw->conf;
	struct ath_hw *ah = sc->sc_ah;
	bool all_wiphys_idle = false, disable_radio = false;

	mutex_lock(&sc->mutex);

	/* Leave this as the first check */
	if (changed & IEEE80211_CONF_CHANGE_IDLE) {

		spin_lock_bh(&sc->wiphy_lock);
		all_wiphys_idle =  ath9k_all_wiphys_idle(sc);
		spin_unlock_bh(&sc->wiphy_lock);

		if (conf->flags & IEEE80211_CONF_IDLE){
			if (all_wiphys_idle)
				disable_radio = true;
		}
		else if (all_wiphys_idle) {
			ath_radio_enable(sc);
			DPRINTF(sc, ATH_DBG_CONFIG,
				"not-idle: enabling radio\n");
		}
	}

	if (changed & IEEE80211_CONF_CHANGE_PS) {
		if (conf->flags & IEEE80211_CONF_PS) {
			if (!(ah->caps.hw_caps &
@@ -2330,6 +2349,11 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
	if (changed & IEEE80211_CONF_CHANGE_POWER)
		sc->config.txpowlimit = 2 * conf->power_level;

	if (disable_radio) {
		DPRINTF(sc, ATH_DBG_CONFIG, "idle: disabling radio\n");
		ath_radio_disable(sc);
	}

	mutex_unlock(&sc->mutex);

	return 0;
+17 −0
Original line number Diff line number Diff line
@@ -660,3 +660,20 @@ void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int)
		queue_delayed_work(sc->hw->workqueue, &sc->wiphy_work,
				   sc->wiphy_scheduler_int);
}

/* caller must hold wiphy_lock */
bool ath9k_all_wiphys_idle(struct ath_softc *sc)
{
	unsigned int i;
	if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE) {
		return false;
	}
	for (i = 0; i < sc->num_sec_wiphy; i++) {
		struct ath_wiphy *aphy = sc->sec_wiphy[i];
		if (!aphy)
			continue;
		if (aphy->state != ATH_WIPHY_INACTIVE)
			return false;
	}
	return true;
}