diff options
author | Sujith <Sujith.Manoharan@atheros.com> | 2008-10-29 00:46:06 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-11-10 15:14:57 -0500 |
commit | 5640b08ef7e88b606c740e746cb77bc97d78508e (patch) | |
tree | 355d8e4d2315e8b88b01521c8a79be52fd5d5429 | |
parent | a37c2c79404940dfc5e88c851c3de5328975b1a9 (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.c | 40 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/core.c | 116 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/core.h | 16 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/main.c | 80 | ||||
-rw-r--r-- | drivers/net/wireless/ath9k/rc.c | 8 |
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 | */ |
245 | static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id) | 247 | static 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 | */ |
301 | int ath_beacon_alloc(struct ath_softc *sc, int if_id) | 306 | int 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 | */ |
653 | void ath_beacon_config(struct ath_softc *sc, int if_id) | 661 | void 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 | |||
648 | int 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 | |||
701 | int 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 | |||
732 | int 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 | ||
1359 | void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, int if_id) | 1249 | void 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, | |||
635 | int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); | 635 | int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); |
636 | void ath_newassoc(struct ath_softc *sc, | 636 | void ath_newassoc(struct ath_softc *sc, |
637 | struct ath_node *node, int isnew, int isuapsd); | 637 | struct ath_node *node, int isnew, int isuapsd); |
638 | void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, | 638 | void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta); |
639 | int if_id); | ||
640 | void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta); | 639 | void 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 */ |
703 | struct ath_vap { | 702 | struct 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 | ||
713 | int ath_vap_attach(struct ath_softc *sc, | ||
714 | int if_id, | ||
715 | struct ieee80211_vif *if_data, | ||
716 | enum ath9k_opmode opmode); | ||
717 | int ath_vap_detach(struct ath_softc *sc, int if_id); | ||
718 | int 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 | ||
315 | static void ath9k_bss_assoc_info(struct ath_softc *sc, | 315 | static 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 | ||
1184 | static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | 1172 | static 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 | |||
1372 | static void ath9k_sta_notify(struct ieee80211_hw *hw, | 1350 | static 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 | ||
2043 | static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) | 2043 | static 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, |