aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/beacon.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/beacon.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c75
1 files changed, 13 insertions, 62 deletions
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index c8a4558f79ba..f43d85a302c4 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -76,22 +76,13 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
76 ds = bf->bf_desc; 76 ds = bf->bf_desc;
77 flags = ATH9K_TXDESC_NOACK; 77 flags = ATH9K_TXDESC_NOACK;
78 78
79 if (((sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || 79 ds->ds_link = 0;
80 (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) && 80 /*
81 (ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) { 81 * Switch antenna every beacon.
82 ds->ds_link = bf->bf_daddr; /* self-linked */ 82 * Should only switch every beacon period, not for every SWBA
83 flags |= ATH9K_TXDESC_VEOL; 83 * XXX assumes two antennae
84 /* Let hardware handle antenna switching. */ 84 */
85 antenna = 0; 85 antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1);
86 } else {
87 ds->ds_link = 0;
88 /*
89 * Switch antenna every beacon.
90 * Should only switch every beacon period, not for every SWBA
91 * XXX assumes two antennae
92 */
93 antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1);
94 }
95 86
96 sband = &sc->sbands[common->hw->conf.channel->band]; 87 sband = &sc->sbands[common->hw->conf.channel->band];
97 rate = sband->bitrates[rateidx].hw_value; 88 rate = sband->bitrates[rateidx].hw_value;
@@ -215,36 +206,6 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
215 return bf; 206 return bf;
216} 207}
217 208
218/*
219 * Startup beacon transmission for adhoc mode when they are sent entirely
220 * by the hardware using the self-linked descriptor + veol trick.
221*/
222static void ath_beacon_start_adhoc(struct ath_softc *sc,
223 struct ieee80211_vif *vif)
224{
225 struct ath_hw *ah = sc->sc_ah;
226 struct ath_common *common = ath9k_hw_common(ah);
227 struct ath_buf *bf;
228 struct ath_vif *avp;
229 struct sk_buff *skb;
230
231 avp = (void *)vif->drv_priv;
232
233 if (avp->av_bcbuf == NULL)
234 return;
235
236 bf = avp->av_bcbuf;
237 skb = bf->bf_mpdu;
238
239 ath_beacon_setup(sc, avp, bf, 0);
240
241 /* NB: caller is known to have already stopped tx dma */
242 ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bf->bf_daddr);
243 ath9k_hw_txstart(ah, sc->beacon.beaconq);
244 ath_print(common, ATH_DBG_BEACON, "TXDP%u = %llx (%p)\n",
245 sc->beacon.beaconq, ito64(bf->bf_daddr), bf->bf_desc);
246}
247
248int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif) 209int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
249{ 210{
250 struct ath_softc *sc = aphy->sc; 211 struct ath_softc *sc = aphy->sc;
@@ -265,7 +226,8 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
265 list_del(&avp->av_bcbuf->list); 226 list_del(&avp->av_bcbuf->list);
266 227
267 if (sc->sc_ah->opmode == NL80211_IFTYPE_AP || 228 if (sc->sc_ah->opmode == NL80211_IFTYPE_AP ||
268 !(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) { 229 sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC ||
230 sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) {
269 int slot; 231 int slot;
270 /* 232 /*
271 * Assign the vif to a beacon xmit slot. As 233 * Assign the vif to a beacon xmit slot. As
@@ -274,17 +236,11 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
274 avp->av_bslot = 0; 236 avp->av_bslot = 0;
275 for (slot = 0; slot < ATH_BCBUF; slot++) 237 for (slot = 0; slot < ATH_BCBUF; slot++)
276 if (sc->beacon.bslot[slot] == NULL) { 238 if (sc->beacon.bslot[slot] == NULL) {
277 /*
278 * XXX hack, space out slots to better
279 * deal with misses
280 */
281 if (slot+1 < ATH_BCBUF &&
282 sc->beacon.bslot[slot+1] == NULL) {
283 avp->av_bslot = slot+1;
284 break;
285 }
286 avp->av_bslot = slot; 239 avp->av_bslot = slot;
240
287 /* NB: keep looking for a double slot */ 241 /* NB: keep looking for a double slot */
242 if (slot == 0 || !sc->beacon.bslot[slot-1])
243 break;
288 } 244 }
289 BUG_ON(sc->beacon.bslot[avp->av_bslot] != NULL); 245 BUG_ON(sc->beacon.bslot[avp->av_bslot] != NULL);
290 sc->beacon.bslot[avp->av_bslot] = vif; 246 sc->beacon.bslot[avp->av_bslot] = vif;
@@ -721,8 +677,7 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
721 * self-linked tx descriptor and let the hardware deal with things. 677 * self-linked tx descriptor and let the hardware deal with things.
722 */ 678 */
723 intval |= ATH9K_BEACON_ENA; 679 intval |= ATH9K_BEACON_ENA;
724 if (!(ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) 680 ah->imask |= ATH9K_INT_SWBA;
725 ah->imask |= ATH9K_INT_SWBA;
726 681
727 ath_beaconq_config(sc); 682 ath_beaconq_config(sc);
728 683
@@ -732,10 +687,6 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
732 ath9k_beacon_init(sc, nexttbtt, intval); 687 ath9k_beacon_init(sc, nexttbtt, intval);
733 sc->beacon.bmisscnt = 0; 688 sc->beacon.bmisscnt = 0;
734 ath9k_hw_set_interrupts(ah, ah->imask); 689 ath9k_hw_set_interrupts(ah, ah->imask);
735
736 /* FIXME: Handle properly when vif is NULL */
737 if (vif && ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)
738 ath_beacon_start_adhoc(sc, vif);
739} 690}
740 691
741void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) 692void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)