aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k
diff options
context:
space:
mode:
authorSujith Manoharan <c_manoha@qca.qualcomm.com>2012-07-17 07:46:22 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-07-17 15:11:39 -0400
commitfb6e252f8d262d05da3ae023b4a6f83d0eec17d9 (patch)
treedb4e955be34e30a5b5882bee56f427464ca2eb9b /drivers/net/wireless/ath/ath9k
parent2f8e82e8ab4629e648925c566cc26bdcf25f0aec (diff)
ath9k: Cleanup the beacon tasklet
Remove unused variables, use a helper function to choose the slot and reset beaconing status at one place. Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k')
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c126
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c2
3 files changed, 63 insertions, 68 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 4aca1e5dd712..41219a5e7f53 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -401,7 +401,6 @@ struct ath_beacon {
401 401
402 u32 beaconq; 402 u32 beaconq;
403 u32 bmisscnt; 403 u32 bmisscnt;
404 u32 ast_be_xmit;
405 u32 bc_tstamp; 404 u32 bc_tstamp;
406 struct ieee80211_vif *bslot[ATH_BCBUF]; 405 struct ieee80211_vif *bslot[ATH_BCBUF];
407 int slottime; 406 int slottime;
@@ -415,7 +414,7 @@ struct ath_beacon {
415 bool tx_last; 414 bool tx_last;
416}; 415};
417 416
418void ath_beacon_tasklet(unsigned long data); 417void ath9k_beacon_tasklet(unsigned long data);
419bool ath9k_allow_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif); 418bool ath9k_allow_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif);
420void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif, 419void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif,
421 u32 changed); 420 u32 changed);
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index f2a2131c5ce5..006ae99d2f59 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -68,7 +68,7 @@ static void ath9k_beaconq_config(struct ath_softc *sc)
68 * up rate codes, and channel flags. Beacons are always sent out at the 68 * up rate codes, and channel flags. Beacons are always sent out at the
69 * lowest rate, and are not retried. 69 * lowest rate, and are not retried.
70*/ 70*/
71static void ath_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif, 71static void ath9k_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif,
72 struct ath_buf *bf, int rateidx) 72 struct ath_buf *bf, int rateidx)
73{ 73{
74 struct sk_buff *skb = bf->bf_mpdu; 74 struct sk_buff *skb = bf->bf_mpdu;
@@ -79,8 +79,6 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif,
79 u8 chainmask = ah->txchainmask; 79 u8 chainmask = ah->txchainmask;
80 u8 rate = 0; 80 u8 rate = 0;
81 81
82 ath9k_reset_beacon_status(sc);
83
84 sband = &sc->sbands[common->hw->conf.channel->band]; 82 sband = &sc->sbands[common->hw->conf.channel->band];
85 rate = sband->bitrates[rateidx].hw_value; 83 rate = sband->bitrates[rateidx].hw_value;
86 if (vif->bss_conf.use_short_preamble) 84 if (vif->bss_conf.use_short_preamble)
@@ -109,7 +107,7 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif,
109 ath9k_hw_set_txdesc(ah, bf->bf_desc, &info); 107 ath9k_hw_set_txdesc(ah, bf->bf_desc, &info);
110} 108}
111 109
112static void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) 110static void ath9k_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
113{ 111{
114 struct ath_softc *sc = hw->priv; 112 struct ath_softc *sc = hw->priv;
115 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 113 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -126,8 +124,8 @@ static void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
126 } 124 }
127} 125}
128 126
129static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, 127static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw,
130 struct ieee80211_vif *vif) 128 struct ieee80211_vif *vif)
131{ 129{
132 struct ath_softc *sc = hw->priv; 130 struct ath_softc *sc = hw->priv;
133 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 131 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -136,15 +134,12 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
136 struct sk_buff *skb; 134 struct sk_buff *skb;
137 struct ath_txq *cabq = sc->beacon.cabq; 135 struct ath_txq *cabq = sc->beacon.cabq;
138 struct ieee80211_tx_info *info; 136 struct ieee80211_tx_info *info;
137 struct ieee80211_mgmt *mgmt_hdr;
139 int cabq_depth; 138 int cabq_depth;
140 139
141 if (avp->av_bcbuf == NULL) 140 if (avp->av_bcbuf == NULL)
142 return NULL; 141 return NULL;
143 142
144 ath9k_reset_beacon_status(sc);
145
146 /* Release the old beacon first */
147
148 bf = avp->av_bcbuf; 143 bf = avp->av_bcbuf;
149 skb = bf->bf_mpdu; 144 skb = bf->bf_mpdu;
150 if (skb) { 145 if (skb) {
@@ -154,14 +149,14 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
154 bf->bf_buf_addr = 0; 149 bf->bf_buf_addr = 0;
155 } 150 }
156 151
157 /* Get a new beacon from mac80211 */
158
159 skb = ieee80211_beacon_get(hw, vif); 152 skb = ieee80211_beacon_get(hw, vif);
160 bf->bf_mpdu = skb;
161 if (skb == NULL) 153 if (skb == NULL)
162 return NULL; 154 return NULL;
163 ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp = 155
164 avp->tsf_adjust; 156 bf->bf_mpdu = skb;
157
158 mgmt_hdr = (struct ieee80211_mgmt *)skb->data;
159 mgmt_hdr->u.beacon.timestamp = avp->tsf_adjust;
165 160
166 info = IEEE80211_SKB_CB(skb); 161 info = IEEE80211_SKB_CB(skb);
167 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { 162 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
@@ -207,10 +202,10 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
207 } 202 }
208 } 203 }
209 204
210 ath_beacon_setup(sc, vif, bf, info->control.rates[0].idx); 205 ath9k_beacon_setup(sc, vif, bf, info->control.rates[0].idx);
211 206
212 while (skb) { 207 while (skb) {
213 ath_tx_cabq(hw, skb); 208 ath9k_tx_cabq(hw, skb);
214 skb = ieee80211_get_buffered_bc(hw, vif); 209 skb = ieee80211_get_buffered_bc(hw, vif);
215 } 210 }
216 211
@@ -268,6 +263,33 @@ void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif)
268 tasklet_enable(&sc->bcon_tasklet); 263 tasklet_enable(&sc->bcon_tasklet);
269} 264}
270 265
266static int ath9k_beacon_choose_slot(struct ath_softc *sc)
267{
268 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
269 struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
270 u16 intval;
271 u32 tsftu;
272 u64 tsf;
273 int slot;
274
275 if (sc->sc_ah->opmode != NL80211_IFTYPE_AP) {
276 ath_dbg(common, BEACON, "slot 0, tsf: %llu\n",
277 ath9k_hw_gettsf64(sc->sc_ah));
278 return 0;
279 }
280
281 intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL;
282 tsf = ath9k_hw_gettsf64(sc->sc_ah);
283 tsf += TU_TO_USEC(sc->sc_ah->config.sw_beacon_response_time);
284 tsftu = TSF_TO_TU((tsf * ATH_BCBUF) >>32, tsf * ATH_BCBUF);
285 slot = (tsftu % (intval * ATH_BCBUF)) / intval;
286
287 ath_dbg(common, BEACON, "slot: %d tsf: %llu tsftu: %u\n",
288 slot, tsf, tsftu / ATH_BCBUF);
289
290 return slot;
291}
292
271void ath9k_set_tsfadjust(struct ath_softc *sc, struct ieee80211_vif *vif) 293void ath9k_set_tsfadjust(struct ath_softc *sc, struct ieee80211_vif *vif)
272{ 294{
273 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 295 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -285,17 +307,15 @@ void ath9k_set_tsfadjust(struct ath_softc *sc, struct ieee80211_vif *vif)
285 (unsigned long long)tsfadjust, avp->av_bslot); 307 (unsigned long long)tsfadjust, avp->av_bslot);
286} 308}
287 309
288void ath_beacon_tasklet(unsigned long data) 310void ath9k_beacon_tasklet(unsigned long data)
289{ 311{
290 struct ath_softc *sc = (struct ath_softc *)data; 312 struct ath_softc *sc = (struct ath_softc *)data;
291 struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
292 struct ath_hw *ah = sc->sc_ah; 313 struct ath_hw *ah = sc->sc_ah;
293 struct ath_common *common = ath9k_hw_common(ah); 314 struct ath_common *common = ath9k_hw_common(ah);
294 struct ath_buf *bf = NULL; 315 struct ath_buf *bf = NULL;
295 struct ieee80211_vif *vif; 316 struct ieee80211_vif *vif;
296 bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); 317 bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA);
297 int slot; 318 int slot;
298 u32 bfaddr, bc = 0;
299 319
300 if (work_pending(&sc->hw_reset_work)) { 320 if (work_pending(&sc->hw_reset_work)) {
301 ath_dbg(common, RESET, 321 ath_dbg(common, RESET,
@@ -331,48 +351,19 @@ void ath_beacon_tasklet(unsigned long data)
331 return; 351 return;
332 } 352 }
333 353
334 /* 354 slot = ath9k_beacon_choose_slot(sc);
335 * Generate beacon frames. we are sending frames 355 vif = sc->beacon.bslot[slot];
336 * staggered so calculate the slot for this frame based
337 * on the tsf to safeguard against missing an swba.
338 */
339
340 356
341 if (ah->opmode == NL80211_IFTYPE_AP) { 357 if (!vif || !vif->bss_conf.enable_beacon)
342 u16 intval; 358 return;
343 u32 tsftu;
344 u64 tsf;
345 359
346 intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL; 360 bf = ath9k_beacon_generate(sc->hw, vif);
347 tsf = ath9k_hw_gettsf64(ah); 361 WARN_ON(!bf);
348 tsf += TU_TO_USEC(ah->config.sw_beacon_response_time);
349 tsftu = TSF_TO_TU((tsf * ATH_BCBUF) >>32, tsf * ATH_BCBUF);
350 slot = (tsftu % (intval * ATH_BCBUF)) / intval;
351 vif = sc->beacon.bslot[slot];
352 362
353 ath_dbg(common, BEACON, 363 if (sc->beacon.bmisscnt != 0) {
354 "slot %d [tsf %llu tsftu %u intval %u] vif %p\n", 364 ath_dbg(common, BSTUCK, "resume beacon xmit after %u misses\n",
355 slot, tsf, tsftu / ATH_BCBUF, intval, vif); 365 sc->beacon.bmisscnt);
356 } else { 366 sc->beacon.bmisscnt = 0;
357 slot = 0;
358 vif = sc->beacon.bslot[slot];
359 }
360
361
362 bfaddr = 0;
363 if (vif) {
364 bf = ath_beacon_generate(sc->hw, vif);
365 if (bf != NULL) {
366 bfaddr = bf->bf_daddr;
367 bc = 1;
368 }
369
370 if (sc->beacon.bmisscnt != 0) {
371 ath_dbg(common, BSTUCK,
372 "resume beacon xmit after %u misses\n",
373 sc->beacon.bmisscnt);
374 sc->beacon.bmisscnt = 0;
375 }
376 } 367 }
377 368
378 /* 369 /*
@@ -392,21 +383,26 @@ void ath_beacon_tasklet(unsigned long data)
392 * set to ATH_BCBUF so this check is a noop. 383 * set to ATH_BCBUF so this check is a noop.
393 */ 384 */
394 if (sc->beacon.updateslot == UPDATE) { 385 if (sc->beacon.updateslot == UPDATE) {
395 sc->beacon.updateslot = COMMIT; /* commit next beacon */ 386 sc->beacon.updateslot = COMMIT;
396 sc->beacon.slotupdate = slot; 387 sc->beacon.slotupdate = slot;
397 } else if (sc->beacon.updateslot == COMMIT && sc->beacon.slotupdate == slot) { 388 } else if (sc->beacon.updateslot == COMMIT &&
389 sc->beacon.slotupdate == slot) {
398 ah->slottime = sc->beacon.slottime; 390 ah->slottime = sc->beacon.slottime;
399 ath9k_hw_init_global_settings(ah); 391 ath9k_hw_init_global_settings(ah);
400 sc->beacon.updateslot = OK; 392 sc->beacon.updateslot = OK;
401 } 393 }
402 if (bfaddr != 0) { 394
395 if (bf) {
396 ath9k_reset_beacon_status(sc);
397
398 ath_dbg(common, BEACON,
399 "Transmitting beacon for slot: %d\n", slot);
400
403 /* NB: cabq traffic should already be queued and primed */ 401 /* NB: cabq traffic should already be queued and primed */
404 ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bfaddr); 402 ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bf->bf_daddr);
405 403
406 if (!edma) 404 if (!edma)
407 ath9k_hw_txstart(ah, sc->beacon.beaconq); 405 ath9k_hw_txstart(ah, sc->beacon.beaconq);
408
409 sc->beacon.ast_be_xmit += bc; /* XXX per-vif? */
410 } 406 }
411} 407}
412 408
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 181977a414e9..f33712140fa5 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -559,7 +559,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
559 spin_lock_init(&sc->debug.samp_lock); 559 spin_lock_init(&sc->debug.samp_lock);
560#endif 560#endif
561 tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); 561 tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
562 tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, 562 tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet,
563 (unsigned long)sc); 563 (unsigned long)sc);
564 564
565 INIT_WORK(&sc->hw_reset_work, ath_reset_work); 565 INIT_WORK(&sc->hw_reset_work, ath_reset_work);