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

Commit 9580a222 authored by Jouni Malinen's avatar Jouni Malinen Committed by John W. Linville
Browse files

ath9k: Make start/stop operations aware of virtual wiphys



Instead of always going through initialization/deinitialization steps,
do this only for the first/last wiphy to not break the other wiphys.

Signed-off-by: default avatarJouni Malinen <jouni.malinen@atheros.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 0e2dedf9
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -627,6 +627,7 @@ struct ath_wiphy {
	struct ath_softc *sc; /* shared for all virtual wiphys */
	struct ieee80211_hw *hw;
	enum ath_wiphy_state {
		ATH_WIPHY_INACTIVE,
		ATH_WIPHY_ACTIVE,
		ATH_WIPHY_PAUSING,
		ATH_WIPHY_PAUSED,
@@ -708,5 +709,6 @@ int ath9k_wiphy_pause(struct ath_wiphy *aphy);
int ath9k_wiphy_unpause(struct ath_wiphy *aphy);
int ath9k_wiphy_select(struct ath_wiphy *aphy);
void ath9k_wiphy_chan_work(struct work_struct *work);
bool ath9k_wiphy_started(struct ath_softc *sc);

#endif /* ATH9K_H */
+28 −0
Original line number Diff line number Diff line
@@ -1965,6 +1965,27 @@ static int ath9k_start(struct ieee80211_hw *hw)

	mutex_lock(&sc->mutex);

	if (ath9k_wiphy_started(sc)) {
		if (sc->chan_idx == curchan->hw_value) {
			/*
			 * Already on the operational channel, the new wiphy
			 * can be marked active.
			 */
			aphy->state = ATH_WIPHY_ACTIVE;
			ieee80211_wake_queues(hw);
		} else {
			/*
			 * Another wiphy is on another channel, start the new
			 * wiphy in paused state.
			 */
			aphy->state = ATH_WIPHY_PAUSED;
			ieee80211_stop_queues(hw);
		}
		mutex_unlock(&sc->mutex);
		return 0;
	}
	aphy->state = ATH_WIPHY_ACTIVE;

	/* setup initial channel */

	pos = curchan->hw_value;
@@ -2104,6 +2125,8 @@ static void ath9k_stop(struct ieee80211_hw *hw)
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;

	aphy->state = ATH_WIPHY_INACTIVE;

	if (sc->sc_flags & SC_OP_INVALID) {
		DPRINTF(sc, ATH_DBG_ANY, "Device not present\n");
		return;
@@ -2113,6 +2136,11 @@ static void ath9k_stop(struct ieee80211_hw *hw)

	ieee80211_stop_queues(hw);

	if (ath9k_wiphy_started(sc)) {
		mutex_unlock(&sc->mutex);
		return; /* another wiphy still in use */
	}

	/* make sure h/w will not generate any interrupt
	 * before setting the invalid flag. */
	ath9k_hw_set_interrupts(sc->sc_ah, 0);
+19 −0
Original line number Diff line number Diff line
@@ -477,3 +477,22 @@ int ath9k_wiphy_select(struct ath_wiphy *aphy)

	return 0;
}

bool ath9k_wiphy_started(struct ath_softc *sc)
{
	int i;
	spin_lock_bh(&sc->wiphy_lock);
	if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE) {
		spin_unlock_bh(&sc->wiphy_lock);
		return true;
	}
	for (i = 0; i < sc->num_sec_wiphy; i++) {
		if (sc->sec_wiphy[i] &&
		    sc->sec_wiphy[i]->state != ATH_WIPHY_INACTIVE) {
			spin_unlock_bh(&sc->wiphy_lock);
			return true;
		}
	}
	spin_unlock_bh(&sc->wiphy_lock);
	return false;
}