ath9k: Allow AP mode to be enabled

Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c
index 0d953f9f..9737775 100644
--- a/drivers/net/wireless/ath9k/core.c
+++ b/drivers/net/wireless/ath9k/core.c
@@ -549,9 +549,15 @@
 	 * XXXX
 	 * Disable BMISS interrupt when we're not associated
 	 */
-	ath9k_hw_set_interrupts(ah,
-		sc->sc_imask & ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS));
-	sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
+	if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) {
+		ath9k_hw_set_interrupts(ah, sc->sc_imask & ~ATH9K_INT_BMISS);
+		sc->sc_imask &= ~ATH9K_INT_BMISS;
+	} else {
+		ath9k_hw_set_interrupts(
+			ah,
+			sc->sc_imask & ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS));
+		sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
+	}
 	/* need to reconfigure the beacons when it moves to RUN */
 	sc->sc_flags &= ~SC_OP_BEACONS;
 
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index 7fb57ee..183c76e 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -426,10 +426,13 @@
 	case IEEE80211_IF_TYPE_IBSS:
 		ic_opmode = ATH9K_M_IBSS;
 		break;
+	case IEEE80211_IF_TYPE_AP:
+		ic_opmode = ATH9K_M_HOSTAP;
+		break;
 	default:
 		DPRINTF(sc, ATH_DBG_FATAL,
-			"%s: Only STA and IBSS are supported currently\n",
-			__func__);
+			"%s: Interface type %d not yet supported\n",
+			__func__, conf->type);
 		return -EOPNOTSUPP;
 	}
 
@@ -530,6 +533,7 @@
 				  struct ieee80211_if_conf *conf)
 {
 	struct ath_softc *sc = hw->priv;
+	struct ath_hal *ah = sc->sc_ah;
 	struct ath_vap *avp;
 	u32 rfilt = 0;
 	int error, i;
@@ -542,6 +546,17 @@
 		return -EINVAL;
 	}
 
+	/* TODO: Need to decide which hw opmode to use for multi-interface
+	 * cases */
+	if (vif->type == IEEE80211_IF_TYPE_AP &&
+	    ah->ah_opmode != ATH9K_M_HOSTAP) {
+		ah->ah_opmode = ATH9K_M_HOSTAP;
+		ath9k_hw_setopmode(ah);
+		ath9k_hw_write_associd(ah, sc->sc_myaddr, 0);
+		/* Request full reset to get hw opmode changed properly */
+		sc->sc_flags |= SC_OP_FULL_RESET;
+	}
+
 	if ((conf->changed & IEEE80211_IFCC_BSSID) &&
 	    !is_zero_ether_addr(conf->bssid)) {
 		switch (vif->type) {