struct ath_tx_control txctl;
        int hdrlen, padsize;
 
-       if (aphy->state != ATH_WIPHY_ACTIVE) {
+       if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) {
                printk(KERN_DEBUG "ath9k: %s: TX in unexpected wiphy state "
                       "%d\n", wiphy_name(hw->wiphy), aphy->state);
                goto exit;
                aphy->chan_idx = pos;
                aphy->chan_is_ht = conf_is_ht(conf);
 
-               /* TODO: do not change operation channel immediately if there
-                * are other virtual wiphys that use another channel. For now,
-                * we do the change immediately to allow mac80211-operated scan
-                * to work. Once the scan operation is moved into ath9k, we can
-                * just move the current aphy in PAUSED state if the channel is
-                * changed into something different from the current operation
-                * channel. */
-               ath9k_wiphy_pause_all_forced(sc, aphy);
+               if (aphy->state == ATH_WIPHY_SCAN ||
+                   aphy->state == ATH_WIPHY_ACTIVE)
+                       ath9k_wiphy_pause_all_forced(sc, aphy);
+               else {
+                       /*
+                        * Do not change operational channel based on a paused
+                        * wiphy changes.
+                        */
+                       goto skip_chan_change;
+               }
 
                DPRINTF(sc, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
                        curchan->center_freq);
                }
        }
 
+skip_chan_change:
        if (changed & IEEE80211_CONF_CHANGE_POWER)
                sc->config.txpowlimit = 2 * conf->power_level;
 
        struct ath_wiphy *aphy = hw->priv;
        struct ath_softc *sc = aphy->sc;
 
+       if (ath9k_wiphy_scanning(sc)) {
+               printk(KERN_DEBUG "ath9k: Two wiphys trying to scan at the "
+                      "same time\n");
+               /*
+                * Do not allow the concurrent scanning state for now. This
+                * could be improved with scanning control moved into ath9k.
+                */
+               return;
+       }
+
+       aphy->state = ATH_WIPHY_SCAN;
+       ath9k_wiphy_pause_all_forced(sc, aphy);
+
        mutex_lock(&sc->mutex);
        sc->sc_flags |= SC_OP_SCANNING;
        mutex_unlock(&sc->mutex);
        struct ath_softc *sc = aphy->sc;
 
        mutex_lock(&sc->mutex);
+       aphy->state = ATH_WIPHY_ACTIVE;
        sc->sc_flags &= ~SC_OP_SCANNING;
        mutex_unlock(&sc->mutex);
 }
 
        return ret;
 }
 
+static bool __ath9k_wiphy_scanning(struct ath_softc *sc)
+{
+       int i;
+       if (sc->pri_wiphy->state == ATH_WIPHY_SCAN)
+               return true;
+       for (i = 0; i < sc->num_sec_wiphy; i++) {
+               if (sc->sec_wiphy[i] &&
+                   sc->sec_wiphy[i]->state == ATH_WIPHY_SCAN)
+                       return true;
+       }
+       return false;
+}
+
+bool ath9k_wiphy_scanning(struct ath_softc *sc)
+{
+       bool ret;
+       spin_lock_bh(&sc->wiphy_lock);
+       ret = __ath9k_wiphy_scanning(sc);
+       spin_unlock_bh(&sc->wiphy_lock);
+       return ret;
+}
+
 static int __ath9k_wiphy_unpause(struct ath_wiphy *aphy);
 
 /* caller must hold wiphy_lock */
        bool now;
 
        spin_lock_bh(&sc->wiphy_lock);
+       if (__ath9k_wiphy_scanning(sc)) {
+               /*
+                * For now, we are using mac80211 sw scan and it expects to
+                * have full control over channel changes, so avoid wiphy
+                * scheduling during a scan. This could be optimized if the
+                * scanning control were moved into the driver.
+                */
+               spin_unlock_bh(&sc->wiphy_lock);
+               return -EBUSY;
+       }
        if (__ath9k_wiphy_pausing(sc)) {
                if (sc->wiphy_select_failures == 0)
                        sc->wiphy_select_first_fail = jiffies;
 static void ath9k_wiphy_pause_chan(struct ath_wiphy *aphy,
                                   struct ath_wiphy *selected)
 {
-       if (aphy->chan_idx == selected->chan_idx)
+       if (selected->state == ATH_WIPHY_SCAN) {
+               if (aphy == selected)
+                       return;
+               /*
+                * Pause all other wiphys for the duration of the scan even if
+                * they are on the current channel now.
+                */
+       } else if (aphy->chan_idx == selected->chan_idx)
                return;
        aphy->state = ATH_WIPHY_PAUSED;
        ieee80211_stop_queues(aphy->hw);