aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSujith <Sujith.Manoharan@atheros.com>2008-10-29 00:46:06 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-11-10 15:14:57 -0500
commit5640b08ef7e88b606c740e746cb77bc97d78508e (patch)
tree355d8e4d2315e8b88b01521c8a79be52fd5d5429
parenta37c2c79404940dfc5e88c851c3de5328975b1a9 (diff)
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>
-rw-r--r--drivers/net/wireless/ath9k/beacon.c40
-rw-r--r--drivers/net/wireless/ath9k/core.c116
-rw-r--r--drivers/net/wireless/ath9k/core.h16
-rw-r--r--drivers/net/wireless/ath9k/main.c80
-rw-r--r--drivers/net/wireless/ath9k/rc.c8
5 files changed, 67 insertions, 193 deletions
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c
index b36d3fb2ecc7..d186cd41c235 100644
--- a/drivers/net/wireless/ath9k/beacon.c
+++ b/drivers/net/wireless/ath9k/beacon.c
@@ -152,12 +152,14 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
152 struct ath_vap *avp; 152 struct ath_vap *avp;
153 struct sk_buff *skb; 153 struct sk_buff *skb;
154 struct ath_txq *cabq; 154 struct ath_txq *cabq;
155 struct ieee80211_vif *vif;
155 struct ieee80211_tx_info *info; 156 struct ieee80211_tx_info *info;
156 int cabq_depth; 157 int cabq_depth;
157 158
158 avp = sc->sc_vaps[if_id]; 159 vif = sc->sc_vaps[if_id];
159 ASSERT(avp); 160 ASSERT(vif);
160 161
162 avp = (void *)vif->drv_priv;
161 cabq = sc->sc_cabq; 163 cabq = sc->sc_cabq;
162 164
163 if (avp->av_bcbuf == NULL) { 165 if (avp->av_bcbuf == NULL) {
@@ -174,7 +176,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
174 PCI_DMA_TODEVICE); 176 PCI_DMA_TODEVICE);
175 } 177 }
176 178
177 skb = ieee80211_beacon_get(sc->hw, avp->av_if_data); 179 skb = ieee80211_beacon_get(sc->hw, vif);
178 bf->bf_mpdu = skb; 180 bf->bf_mpdu = skb;
179 if (skb == NULL) 181 if (skb == NULL)
180 return NULL; 182 return NULL;
@@ -196,7 +198,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
196 skb_end_pointer(skb) - skb->head, 198 skb_end_pointer(skb) - skb->head,
197 PCI_DMA_TODEVICE); 199 PCI_DMA_TODEVICE);
198 200
199 skb = ieee80211_get_buffered_bc(sc->hw, avp->av_if_data); 201 skb = ieee80211_get_buffered_bc(sc->hw, vif);
200 202
201 /* 203 /*
202 * if the CABQ traffic from previous DTIM is pending and the current 204 * if the CABQ traffic from previous DTIM is pending and the current
@@ -232,7 +234,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
232 */ 234 */
233 while (skb) { 235 while (skb) {
234 ath_tx_cabq(sc, skb); 236 ath_tx_cabq(sc, skb);
235 skb = ieee80211_get_buffered_bc(sc->hw, avp->av_if_data); 237 skb = ieee80211_get_buffered_bc(sc->hw, vif);
236 } 238 }
237 239
238 return bf; 240 return bf;
@@ -244,13 +246,16 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
244*/ 246*/
245static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id) 247static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id)
246{ 248{
249 struct ieee80211_vif *vif;
247 struct ath_hal *ah = sc->sc_ah; 250 struct ath_hal *ah = sc->sc_ah;
248 struct ath_buf *bf; 251 struct ath_buf *bf;
249 struct ath_vap *avp; 252 struct ath_vap *avp;
250 struct sk_buff *skb; 253 struct sk_buff *skb;
251 254
252 avp = sc->sc_vaps[if_id]; 255 vif = sc->sc_vaps[if_id];
253 ASSERT(avp); 256 ASSERT(vif);
257
258 avp = (void *)vif->drv_priv;
254 259
255 if (avp->av_bcbuf == NULL) { 260 if (avp->av_bcbuf == NULL) {
256 DPRINTF(sc, ATH_DBG_BEACON, "%s: avp=%p av_bcbuf=%p\n", 261 DPRINTF(sc, ATH_DBG_BEACON, "%s: avp=%p av_bcbuf=%p\n",
@@ -300,14 +305,17 @@ int ath_beaconq_setup(struct ath_hal *ah)
300*/ 305*/
301int ath_beacon_alloc(struct ath_softc *sc, int if_id) 306int ath_beacon_alloc(struct ath_softc *sc, int if_id)
302{ 307{
308 struct ieee80211_vif *vif;
303 struct ath_vap *avp; 309 struct ath_vap *avp;
304 struct ieee80211_hdr *hdr; 310 struct ieee80211_hdr *hdr;
305 struct ath_buf *bf; 311 struct ath_buf *bf;
306 struct sk_buff *skb; 312 struct sk_buff *skb;
307 __le64 tstamp; 313 __le64 tstamp;
308 314
309 avp = sc->sc_vaps[if_id]; 315 vif = sc->sc_vaps[if_id];
310 ASSERT(avp); 316 ASSERT(vif);
317
318 avp = (void *)vif->drv_priv;
311 319
312 /* Allocate a beacon descriptor if we haven't done so. */ 320 /* Allocate a beacon descriptor if we haven't done so. */
313 if (!avp->av_bcbuf) { 321 if (!avp->av_bcbuf) {
@@ -363,7 +371,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
363 * FIXME: Fill avp->av_btxctl.txpower and 371 * FIXME: Fill avp->av_btxctl.txpower and
364 * avp->av_btxctl.shortPreamble 372 * avp->av_btxctl.shortPreamble
365 */ 373 */
366 skb = ieee80211_beacon_get(sc->hw, avp->av_if_data); 374 skb = ieee80211_beacon_get(sc->hw, vif);
367 if (skb == NULL) { 375 if (skb == NULL) {
368 DPRINTF(sc, ATH_DBG_BEACON, "%s: cannot get skb\n", 376 DPRINTF(sc, ATH_DBG_BEACON, "%s: cannot get skb\n",
369 __func__); 377 __func__);
@@ -652,15 +660,21 @@ void ath_bstuck_process(struct ath_softc *sc)
652 */ 660 */
653void ath_beacon_config(struct ath_softc *sc, int if_id) 661void ath_beacon_config(struct ath_softc *sc, int if_id)
654{ 662{
663 struct ieee80211_vif *vif;
655 struct ath_hal *ah = sc->sc_ah; 664 struct ath_hal *ah = sc->sc_ah;
656 struct ath_beacon_config conf; 665 struct ath_beacon_config conf;
666 struct ath_vap *avp;
657 enum ath9k_opmode av_opmode; 667 enum ath9k_opmode av_opmode;
658 u32 nexttbtt, intval; 668 u32 nexttbtt, intval;
659 669
660 if (if_id != ATH_IF_ID_ANY) 670 if (if_id != ATH_IF_ID_ANY) {
661 av_opmode = sc->sc_vaps[if_id]->av_opmode; 671 vif = sc->sc_vaps[if_id];
662 else 672 ASSERT(vif);
673 avp = (void *)vif->drv_priv;
674 av_opmode = avp->av_opmode;
675 } else {
663 av_opmode = sc->sc_ah->ah_opmode; 676 av_opmode = sc->sc_ah->ah_opmode;
677 }
664 678
665 memset(&conf, 0, sizeof(struct ath_beacon_config)); 679 memset(&conf, 0, sizeof(struct ath_beacon_config));
666 680
diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c
index 689a28037096..aa1f1fc0886a 100644
--- a/drivers/net/wireless/ath9k/core.c
+++ b/drivers/net/wireless/ath9k/core.c
@@ -14,8 +14,6 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17 /* Implementation of the main "ATH" layer. */
18
19#include "core.h" 17#include "core.h"
20#include "regd.h" 18#include "regd.h"
21 19
@@ -641,114 +639,6 @@ static void ath_ani_calibrate(unsigned long data)
641 mod_timer(&sc->sc_ani.timer, jiffies + msecs_to_jiffies(cal_interval)); 639 mod_timer(&sc->sc_ani.timer, jiffies + msecs_to_jiffies(cal_interval));
642} 640}
643 641
644/******************/
645/* VAP management */
646/******************/
647
648int ath_vap_attach(struct ath_softc *sc,
649 int if_id,
650 struct ieee80211_vif *if_data,
651 enum ath9k_opmode opmode)
652{
653 struct ath_vap *avp;
654
655 if (if_id >= ATH_BCBUF || sc->sc_vaps[if_id] != NULL) {
656 DPRINTF(sc, ATH_DBG_FATAL,
657 "%s: Invalid interface id = %u\n", __func__, if_id);
658 return -EINVAL;
659 }
660
661 switch (opmode) {
662 case ATH9K_M_STA:
663 case ATH9K_M_IBSS:
664 case ATH9K_M_MONITOR:
665 break;
666 case ATH9K_M_HOSTAP:
667 /* XXX not right, beacon buffer is allocated on RUN trans */
668 if (list_empty(&sc->sc_bbuf))
669 return -ENOMEM;
670 break;
671 default:
672 return -EINVAL;
673 }
674
675 /* create ath_vap */
676 avp = kmalloc(sizeof(struct ath_vap), GFP_KERNEL);
677 if (avp == NULL)
678 return -ENOMEM;
679
680 memset(avp, 0, sizeof(struct ath_vap));
681 avp->av_if_data = if_data;
682 /* Set the VAP opmode */
683 avp->av_opmode = opmode;
684 avp->av_bslot = -1;
685
686 if (opmode == ATH9K_M_HOSTAP)
687 ath9k_hw_set_tsfadjust(sc->sc_ah, 1);
688
689 sc->sc_vaps[if_id] = avp;
690 sc->sc_nvaps++;
691 /* Set the device opmode */
692 sc->sc_ah->ah_opmode = opmode;
693
694 /* default VAP configuration */
695 avp->av_config.av_fixed_rateset = IEEE80211_FIXED_RATE_NONE;
696 avp->av_config.av_fixed_retryset = 0x03030303;
697
698 return 0;
699}
700
701int ath_vap_detach(struct ath_softc *sc, int if_id)
702{
703 struct ath_hal *ah = sc->sc_ah;
704 struct ath_vap *avp;
705
706 avp = sc->sc_vaps[if_id];
707 if (avp == NULL) {
708 DPRINTF(sc, ATH_DBG_FATAL, "%s: invalid interface id %u\n",
709 __func__, if_id);
710 return -EINVAL;
711 }
712
713 /*
714 * Quiesce the hardware while we remove the vap. In
715 * particular we need to reclaim all references to the
716 * vap state by any frames pending on the tx queues.
717 *
718 * XXX can we do this w/o affecting other vap's?
719 */
720 ath9k_hw_set_interrupts(ah, 0); /* disable interrupts */
721 ath_draintxq(sc, false); /* stop xmit side */
722 ath_stoprecv(sc); /* stop recv side */
723 ath_flushrecv(sc); /* flush recv queue */
724
725 kfree(avp);
726 sc->sc_vaps[if_id] = NULL;
727 sc->sc_nvaps--;
728
729 return 0;
730}
731
732int ath_vap_config(struct ath_softc *sc,
733 int if_id, struct ath_vap_config *if_config)
734{
735 struct ath_vap *avp;
736
737 if (if_id >= ATH_BCBUF) {
738 DPRINTF(sc, ATH_DBG_FATAL,
739 "%s: Invalid interface id = %u\n", __func__, if_id);
740 return -EINVAL;
741 }
742
743 avp = sc->sc_vaps[if_id];
744 ASSERT(avp != NULL);
745
746 if (avp)
747 memcpy(&avp->av_config, if_config, sizeof(avp->av_config));
748
749 return 0;
750}
751
752/********/ 642/********/
753/* Core */ 643/* Core */
754/********/ 644/********/
@@ -1356,14 +1246,10 @@ void ath_deinit(struct ath_softc *sc)
1356/* Node Management */ 1246/* Node Management */
1357/*******************/ 1247/*******************/
1358 1248
1359void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, int if_id) 1249void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
1360{ 1250{
1361 struct ath_vap *avp;
1362 struct ath_node *an; 1251 struct ath_node *an;
1363 1252
1364 avp = sc->sc_vaps[if_id];
1365 ASSERT(avp != NULL);
1366
1367 an = (struct ath_node *)sta->drv_priv; 1253 an = (struct ath_node *)sta->drv_priv;
1368 1254
1369 if (sc->sc_flags & SC_OP_TXAGGR) 1255 if (sc->sc_flags & SC_OP_TXAGGR)
diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h
index d89dd03eaed7..c03acf7a4900 100644
--- a/drivers/net/wireless/ath9k/core.h
+++ b/drivers/net/wireless/ath9k/core.h
@@ -635,8 +635,7 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
635int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); 635int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
636void ath_newassoc(struct ath_softc *sc, 636void ath_newassoc(struct ath_softc *sc,
637 struct ath_node *node, int isnew, int isuapsd); 637 struct ath_node *node, int isnew, int isuapsd);
638void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, 638void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta);
639 int if_id);
640void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta); 639void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta);
641 640
642/*******************/ 641/*******************/
@@ -701,23 +700,14 @@ struct ath_vap_config {
701 700
702/* driver-specific vap state */ 701/* driver-specific vap state */
703struct ath_vap { 702struct ath_vap {
704 struct ieee80211_vif *av_if_data; 703 int av_bslot; /* beacon slot index */
705 enum ath9k_opmode av_opmode; /* VAP operational mode */ 704 enum ath9k_opmode av_opmode; /* VAP operational mode */
706 struct ath_buf *av_bcbuf; /* beacon buffer */ 705 struct ath_buf *av_bcbuf; /* beacon buffer */
707 struct ath_tx_control av_btxctl; /* txctl information for beacon */ 706 struct ath_tx_control av_btxctl; /* txctl information for beacon */
708 int av_bslot; /* beacon slot index */
709 struct ath_vap_config av_config;/* vap configuration parameters*/ 707 struct ath_vap_config av_config;/* vap configuration parameters*/
710 struct ath_rate_node *rc_node; 708 struct ath_rate_node *rc_node;
711}; 709};
712 710
713int ath_vap_attach(struct ath_softc *sc,
714 int if_id,
715 struct ieee80211_vif *if_data,
716 enum ath9k_opmode opmode);
717int ath_vap_detach(struct ath_softc *sc, int if_id);
718int ath_vap_config(struct ath_softc *sc,
719 int if_id, struct ath_vap_config *if_config);
720
721/*********************/ 711/*********************/
722/* Antenna diversity */ 712/* Antenna diversity */
723/*********************/ 713/*********************/
@@ -925,7 +915,7 @@ struct ath_softc {
925 915
926 u8 sc_nbcnvaps; /* # of vaps sending beacons */ 916 u8 sc_nbcnvaps; /* # of vaps sending beacons */
927 u16 sc_nvaps; /* # of active virtual ap's */ 917 u16 sc_nvaps; /* # of active virtual ap's */
928 struct ath_vap *sc_vaps[ATH_BCBUF]; 918 struct ieee80211_vif *sc_vaps[ATH_BCBUF];
929 919
930 u8 sc_mcastantenna; 920 u8 sc_mcastantenna;
931 u8 sc_defant; /* current default antenna */ 921 u8 sc_defant; /* current default antenna */
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index 0a0eb7ce0f5f..0194e44034e0 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -162,7 +162,7 @@ static int ath_key_config(struct ath_softc *sc,
162 if (!sc->sc_vaps[0]) 162 if (!sc->sc_vaps[0])
163 return -EIO; 163 return -EIO;
164 164
165 vif = sc->sc_vaps[0]->av_if_data; 165 vif = sc->sc_vaps[0];
166 opmode = vif->type; 166 opmode = vif->type;
167 167
168 /* 168 /*
@@ -313,11 +313,12 @@ static void ath9k_ht_conf(struct ath_softc *sc,
313} 313}
314 314
315static void ath9k_bss_assoc_info(struct ath_softc *sc, 315static void ath9k_bss_assoc_info(struct ath_softc *sc,
316 struct ieee80211_vif *vif,
316 struct ieee80211_bss_conf *bss_conf) 317 struct ieee80211_bss_conf *bss_conf)
317{ 318{
318 struct ieee80211_hw *hw = sc->hw; 319 struct ieee80211_hw *hw = sc->hw;
319 struct ieee80211_channel *curchan = hw->conf.channel; 320 struct ieee80211_channel *curchan = hw->conf.channel;
320 struct ath_vap *avp; 321 struct ath_vap *avp = (void *)vif->drv_priv;
321 int pos; 322 int pos;
322 323
323 if (bss_conf->assoc) { 324 if (bss_conf->assoc) {
@@ -325,13 +326,6 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
325 __func__, 326 __func__,
326 bss_conf->aid); 327 bss_conf->aid);
327 328
328 avp = sc->sc_vaps[0];
329 if (avp == NULL) {
330 DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid interface\n",
331 __func__);
332 return;
333 }
334
335 /* New association, store aid */ 329 /* New association, store aid */
336 if (avp->av_opmode == ATH9K_M_STA) { 330 if (avp->av_opmode == ATH9K_M_STA) {
337 sc->sc_curaid = bss_conf->aid; 331 sc->sc_curaid = bss_conf->aid;
@@ -906,6 +900,7 @@ static int ath_attach(u16 devid,
906 900
907 hw->queues = 4; 901 hw->queues = 4;
908 hw->sta_data_size = sizeof(struct ath_node); 902 hw->sta_data_size = sizeof(struct ath_node);
903 hw->vif_data_size = sizeof(struct ath_vap);
909 904
910 /* Register rate control */ 905 /* Register rate control */
911 hw->rate_control_algorithm = "ath9k_rate_control"; 906 hw->rate_control_algorithm = "ath9k_rate_control";
@@ -1091,7 +1086,8 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
1091 struct ieee80211_if_init_conf *conf) 1086 struct ieee80211_if_init_conf *conf)
1092{ 1087{
1093 struct ath_softc *sc = hw->priv; 1088 struct ath_softc *sc = hw->priv;
1094 int error, ic_opmode = 0; 1089 struct ath_vap *avp = (void *)conf->vif->drv_priv;
1090 int ic_opmode = 0;
1095 1091
1096 /* Support only vap for now */ 1092 /* Support only vap for now */
1097 1093
@@ -1119,13 +1115,22 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
1119 __func__, 1115 __func__,
1120 ic_opmode); 1116 ic_opmode);
1121 1117
1122 error = ath_vap_attach(sc, 0, conf->vif, ic_opmode); 1118 /* Set the VAP opmode */
1123 if (error) { 1119 avp->av_opmode = ic_opmode;
1124 DPRINTF(sc, ATH_DBG_FATAL, 1120 avp->av_bslot = -1;
1125 "%s: Unable to attach vap, error: %d\n", 1121
1126 __func__, error); 1122 if (ic_opmode == ATH9K_M_HOSTAP)
1127 return error; 1123 ath9k_hw_set_tsfadjust(sc->sc_ah, 1);
1128 } 1124
1125 sc->sc_vaps[0] = conf->vif;
1126 sc->sc_nvaps++;
1127
1128 /* Set the device opmode */
1129 sc->sc_ah->ah_opmode = ic_opmode;
1130
1131 /* default VAP configuration */
1132 avp->av_config.av_fixed_rateset = IEEE80211_FIXED_RATE_NONE;
1133 avp->av_config.av_fixed_retryset = 0x03030303;
1129 1134
1130 if (conf->type == NL80211_IFTYPE_AP) { 1135 if (conf->type == NL80211_IFTYPE_AP) {
1131 /* TODO: is this a suitable place to start ANI for AP mode? */ 1136 /* TODO: is this a suitable place to start ANI for AP mode? */
@@ -1141,27 +1146,16 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
1141 struct ieee80211_if_init_conf *conf) 1146 struct ieee80211_if_init_conf *conf)
1142{ 1147{
1143 struct ath_softc *sc = hw->priv; 1148 struct ath_softc *sc = hw->priv;
1144 struct ath_vap *avp; 1149 struct ath_vap *avp = (void *)conf->vif->drv_priv;
1145 int error;
1146 1150
1147 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Detach VAP\n", __func__); 1151 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Detach VAP\n", __func__);
1148 1152
1149 avp = sc->sc_vaps[0];
1150 if (avp == NULL) {
1151 DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid interface\n",
1152 __func__);
1153 return;
1154 }
1155
1156#ifdef CONFIG_SLOW_ANT_DIV 1153#ifdef CONFIG_SLOW_ANT_DIV
1157 ath_slow_ant_div_stop(&sc->sc_antdiv); 1154 ath_slow_ant_div_stop(&sc->sc_antdiv);
1158#endif 1155#endif
1159 /* Stop ANI */ 1156 /* Stop ANI */
1160 del_timer_sync(&sc->sc_ani.timer); 1157 del_timer_sync(&sc->sc_ani.timer);
1161 1158
1162 /* Update ratectrl */
1163 ath_rate_newstate(sc, avp);
1164
1165 /* Reclaim beacon resources */ 1159 /* Reclaim beacon resources */
1166 if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP || 1160 if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP ||
1167 sc->sc_ah->ah_opmode == ATH9K_M_IBSS) { 1161 sc->sc_ah->ah_opmode == ATH9K_M_IBSS) {
@@ -1169,16 +1163,10 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
1169 ath_beacon_return(sc, avp); 1163 ath_beacon_return(sc, avp);
1170 } 1164 }
1171 1165
1172 /* Set interrupt mask */
1173 sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
1174 ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask & ~ATH9K_INT_GLOBAL);
1175 sc->sc_flags &= ~SC_OP_BEACONS; 1166 sc->sc_flags &= ~SC_OP_BEACONS;
1176 1167
1177 error = ath_vap_detach(sc, 0); 1168 sc->sc_vaps[0] = NULL;
1178 if (error) 1169 sc->sc_nvaps--;
1179 DPRINTF(sc, ATH_DBG_FATAL,
1180 "%s: Unable to detach vap, error: %d\n",
1181 __func__, error);
1182} 1170}
1183 1171
1184static int ath9k_config(struct ieee80211_hw *hw, u32 changed) 1172static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
@@ -1226,17 +1214,10 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
1226{ 1214{
1227 struct ath_softc *sc = hw->priv; 1215 struct ath_softc *sc = hw->priv;
1228 struct ath_hal *ah = sc->sc_ah; 1216 struct ath_hal *ah = sc->sc_ah;
1229 struct ath_vap *avp; 1217 struct ath_vap *avp = (void *)vif->drv_priv;
1230 u32 rfilt = 0; 1218 u32 rfilt = 0;
1231 int error, i; 1219 int error, i;
1232 1220
1233 avp = sc->sc_vaps[0];
1234 if (avp == NULL) {
1235 DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid interface\n",
1236 __func__);
1237 return -EINVAL;
1238 }
1239
1240 /* TODO: Need to decide which hw opmode to use for multi-interface 1221 /* TODO: Need to decide which hw opmode to use for multi-interface
1241 * cases */ 1222 * cases */
1242 if (vif->type == NL80211_IFTYPE_AP && 1223 if (vif->type == NL80211_IFTYPE_AP &&
@@ -1317,7 +1298,7 @@ static int ath9k_config_interface(struct ieee80211_hw *hw,
1317 } 1298 }
1318 1299
1319 /* Check for WLAN_CAPABILITY_PRIVACY ? */ 1300 /* Check for WLAN_CAPABILITY_PRIVACY ? */
1320 if ((avp->av_opmode != NL80211_IFTYPE_STATION)) { 1301 if ((avp->av_opmode != ATH9K_M_STA)) {
1321 for (i = 0; i < IEEE80211_WEP_NKID; i++) 1302 for (i = 0; i < IEEE80211_WEP_NKID; i++)
1322 if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i)) 1303 if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i))
1323 ath9k_hw_keysetmac(sc->sc_ah, 1304 ath9k_hw_keysetmac(sc->sc_ah,
@@ -1366,9 +1347,6 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw,
1366 __func__, sc->rx_filter); 1347 __func__, sc->rx_filter);
1367} 1348}
1368 1349
1369/* Only a single interface is currently supported,
1370 so pass 0 as the interface id to ath_node_attach */
1371
1372static void ath9k_sta_notify(struct ieee80211_hw *hw, 1350static void ath9k_sta_notify(struct ieee80211_hw *hw,
1373 struct ieee80211_vif *vif, 1351 struct ieee80211_vif *vif,
1374 enum sta_notify_cmd cmd, 1352 enum sta_notify_cmd cmd,
@@ -1378,7 +1356,7 @@ static void ath9k_sta_notify(struct ieee80211_hw *hw,
1378 1356
1379 switch (cmd) { 1357 switch (cmd) {
1380 case STA_NOTIFY_ADD: 1358 case STA_NOTIFY_ADD:
1381 ath_node_attach(sc, sta, 0); 1359 ath_node_attach(sc, sta);
1382 break; 1360 break;
1383 case STA_NOTIFY_REMOVE: 1361 case STA_NOTIFY_REMOVE:
1384 ath_node_detach(sc, sta); 1362 ath_node_detach(sc, sta);
@@ -1496,7 +1474,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1496 DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed ASSOC %d\n", 1474 DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed ASSOC %d\n",
1497 __func__, 1475 __func__,
1498 bss_conf->assoc); 1476 bss_conf->assoc);
1499 ath9k_bss_assoc_info(sc, bss_conf); 1477 ath9k_bss_assoc_info(sc, vif, bss_conf);
1500 } 1478 }
1501} 1479}
1502 1480
diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c
index ff283dca7328..fecc8390d4d8 100644
--- a/drivers/net/wireless/ath9k/rc.c
+++ b/drivers/net/wireless/ath9k/rc.c
@@ -2042,12 +2042,18 @@ static void ath_rate_free(void *priv)
2042 2042
2043static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) 2043static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
2044{ 2044{
2045 struct ieee80211_vif *vif;
2045 struct ath_softc *sc = priv; 2046 struct ath_softc *sc = priv;
2046 struct ath_vap *avp = sc->sc_vaps[0]; 2047 struct ath_vap *avp;
2047 struct ath_rate_node *rate_priv; 2048 struct ath_rate_node *rate_priv;
2048 2049
2049 DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__); 2050 DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__);
2050 2051
2052 vif = sc->sc_vaps[0];
2053 ASSERT(vif);
2054
2055 avp = (void *)vif->drv_priv;
2056
2051 rate_priv = ath_rate_node_alloc(avp, sc->sc_rc, gfp); 2057 rate_priv = ath_rate_node_alloc(avp, sc->sc_rc, gfp);
2052 if (!rate_priv) { 2058 if (!rate_priv) {
2053 DPRINTF(sc, ATH_DBG_FATAL, 2059 DPRINTF(sc, ATH_DBG_FATAL,