ath9k: Revamp VAP management

Remove the internal VAP management routines
and embed ath_vap in mac80211's driver private area
provided in ieee80211_vif.

Signed-off-by: Sujith <Sujith.Manoharan@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index 0a0eb7c..0194e44 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -162,7 +162,7 @@
 	if (!sc->sc_vaps[0])
 		return -EIO;
 
-	vif = sc->sc_vaps[0]->av_if_data;
+	vif = sc->sc_vaps[0];
 	opmode = vif->type;
 
 	/*
@@ -313,11 +313,12 @@
 }
 
 static void ath9k_bss_assoc_info(struct ath_softc *sc,
+				 struct ieee80211_vif *vif,
 				 struct ieee80211_bss_conf *bss_conf)
 {
 	struct ieee80211_hw *hw = sc->hw;
 	struct ieee80211_channel *curchan = hw->conf.channel;
-	struct ath_vap *avp;
+	struct ath_vap *avp = (void *)vif->drv_priv;
 	int pos;
 
 	if (bss_conf->assoc) {
@@ -325,13 +326,6 @@
 			__func__,
 			bss_conf->aid);
 
-		avp = sc->sc_vaps[0];
-		if (avp == NULL) {
-			DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid interface\n",
-				__func__);
-			return;
-		}
-
 		/* New association, store aid */
 		if (avp->av_opmode == ATH9K_M_STA) {
 			sc->sc_curaid = bss_conf->aid;
@@ -906,6 +900,7 @@
 
 	hw->queues = 4;
 	hw->sta_data_size = sizeof(struct ath_node);
+	hw->vif_data_size = sizeof(struct ath_vap);
 
 	/* Register rate control */
 	hw->rate_control_algorithm = "ath9k_rate_control";
@@ -1091,7 +1086,8 @@
 			       struct ieee80211_if_init_conf *conf)
 {
 	struct ath_softc *sc = hw->priv;
-	int error, ic_opmode = 0;
+	struct ath_vap *avp = (void *)conf->vif->drv_priv;
+	int ic_opmode = 0;
 
 	/* Support only vap for now */
 
@@ -1119,13 +1115,22 @@
 		__func__,
 		ic_opmode);
 
-	error = ath_vap_attach(sc, 0, conf->vif, ic_opmode);
-	if (error) {
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"%s: Unable to attach vap, error: %d\n",
-			__func__, error);
-		return error;
-	}
+	/* Set the VAP opmode */
+	avp->av_opmode = ic_opmode;
+	avp->av_bslot = -1;
+
+	if (ic_opmode == ATH9K_M_HOSTAP)
+		ath9k_hw_set_tsfadjust(sc->sc_ah, 1);
+
+	sc->sc_vaps[0] = conf->vif;
+	sc->sc_nvaps++;
+
+	/* Set the device opmode */
+	sc->sc_ah->ah_opmode = ic_opmode;
+
+	/* default VAP configuration */
+	avp->av_config.av_fixed_rateset = IEEE80211_FIXED_RATE_NONE;
+	avp->av_config.av_fixed_retryset = 0x03030303;
 
 	if (conf->type == NL80211_IFTYPE_AP) {
 		/* TODO: is this a suitable place to start ANI for AP mode? */
@@ -1141,27 +1146,16 @@
 				   struct ieee80211_if_init_conf *conf)
 {
 	struct ath_softc *sc = hw->priv;
-	struct ath_vap *avp;
-	int error;
+	struct ath_vap *avp = (void *)conf->vif->drv_priv;
 
 	DPRINTF(sc, ATH_DBG_CONFIG, "%s: Detach VAP\n", __func__);
 
-	avp = sc->sc_vaps[0];
-	if (avp == NULL) {
-		DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid interface\n",
-			__func__);
-		return;
-	}
-
 #ifdef CONFIG_SLOW_ANT_DIV
 	ath_slow_ant_div_stop(&sc->sc_antdiv);
 #endif
 	/* Stop ANI */
 	del_timer_sync(&sc->sc_ani.timer);
 
-	/* Update ratectrl */
-	ath_rate_newstate(sc, avp);
-
 	/* Reclaim beacon resources */
 	if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP ||
 	    sc->sc_ah->ah_opmode == ATH9K_M_IBSS) {
@@ -1169,16 +1163,10 @@
 		ath_beacon_return(sc, avp);
 	}
 
-	/* Set interrupt mask */
-	sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
-	ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask & ~ATH9K_INT_GLOBAL);
 	sc->sc_flags &= ~SC_OP_BEACONS;
 
-	error = ath_vap_detach(sc, 0);
-	if (error)
-		DPRINTF(sc, ATH_DBG_FATAL,
-			"%s: Unable to detach vap, error: %d\n",
-			__func__, error);
+	sc->sc_vaps[0] = NULL;
+	sc->sc_nvaps--;
 }
 
 static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
@@ -1226,17 +1214,10 @@
 {
 	struct ath_softc *sc = hw->priv;
 	struct ath_hal *ah = sc->sc_ah;
-	struct ath_vap *avp;
+	struct ath_vap *avp = (void *)vif->drv_priv;
 	u32 rfilt = 0;
 	int error, i;
 
-	avp = sc->sc_vaps[0];
-	if (avp == NULL) {
-		DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid interface\n",
-			__func__);
-		return -EINVAL;
-	}
-
 	/* TODO: Need to decide which hw opmode to use for multi-interface
 	 * cases */
 	if (vif->type == NL80211_IFTYPE_AP &&
@@ -1317,7 +1298,7 @@
 	}
 
 	/* Check for WLAN_CAPABILITY_PRIVACY ? */
-	if ((avp->av_opmode != NL80211_IFTYPE_STATION)) {
+	if ((avp->av_opmode != ATH9K_M_STA)) {
 		for (i = 0; i < IEEE80211_WEP_NKID; i++)
 			if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i))
 				ath9k_hw_keysetmac(sc->sc_ah,
@@ -1366,9 +1347,6 @@
 		__func__, sc->rx_filter);
 }
 
-/* Only a single interface is currently supported,
-   so pass 0 as the interface id to ath_node_attach */
-
 static void ath9k_sta_notify(struct ieee80211_hw *hw,
 			     struct ieee80211_vif *vif,
 			     enum sta_notify_cmd cmd,
@@ -1378,7 +1356,7 @@
 
 	switch (cmd) {
 	case STA_NOTIFY_ADD:
-		ath_node_attach(sc, sta, 0);
+		ath_node_attach(sc, sta);
 		break;
 	case STA_NOTIFY_REMOVE:
 		ath_node_detach(sc, sta);
@@ -1496,7 +1474,7 @@
 		DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed ASSOC %d\n",
 			__func__,
 			bss_conf->assoc);
-		ath9k_bss_assoc_info(sc, bss_conf);
+		ath9k_bss_assoc_info(sc, vif, bss_conf);
 	}
 }