aboutsummaryrefslogtreecommitdiffstats
path: root/package/ath9k/src/drivers/net/wireless/ath9k/beacon.c
diff options
context:
space:
mode:
Diffstat (limited to 'package/ath9k/src/drivers/net/wireless/ath9k/beacon.c')
-rw-r--r--package/ath9k/src/drivers/net/wireless/ath9k/beacon.c204
1 files changed, 69 insertions, 135 deletions
diff --git a/package/ath9k/src/drivers/net/wireless/ath9k/beacon.c b/package/ath9k/src/drivers/net/wireless/ath9k/beacon.c
index 1a23fd164b..596591ec5a 100644
--- a/package/ath9k/src/drivers/net/wireless/ath9k/beacon.c
+++ b/package/ath9k/src/drivers/net/wireless/ath9k/beacon.c
@@ -45,7 +45,7 @@ static int ath_beaconq_config(struct ath_softc *sc)
}
if (!ath9k_hw_settxqueueprops(ah, sc->sc_bhalq, &qi)) {
- DPRINTF(sc, ATH_DEBUG_FATAL,
+ DPRINTF(sc, ATH_DBG_FATAL,
"%s: unable to update h/w beacon queue parameters\n",
__func__);
return 0;
@@ -76,7 +76,7 @@ static void ath_beacon_setup(struct ath_softc *sc,
int ctsduration = 0;
struct hal_11n_rate_series series[4];
- DPRINTF(sc, ATH_DEBUG_BEACON, "%s: m %p len %u\n",
+ DPRINTF(sc, ATH_DBG_BEACON, "%s: m %p len %u\n",
__func__, skb, skb->len);
/* setup descriptors */
@@ -84,7 +84,7 @@ static void ath_beacon_setup(struct ath_softc *sc,
flags = HAL_TXDESC_NOACK;
- if (sc->sc_opmode == HAL_M_IBSS && sc->sc_hasveol) {
+ if (sc->sc_opmode == HAL_M_IBSS && ah->ah_caps.halVEOLSupport) {
ds->ds_link = bf->bf_daddr; /* self-linked */
flags |= HAL_TXDESC_VEOL;
/* Let hardware handle antenna switching. */
@@ -97,11 +97,7 @@ static void ath_beacon_setup(struct ath_softc *sc,
* SWBA's
* XXX assumes two antenna
*/
- if (sc->sc_stagbeacons)
- antenna = ((sc->ast_be_xmit /
- sc->sc_nbcnvaps) & 1 ? 2 : 1);
- else
- antenna = (sc->ast_be_xmit & 1 ? 2 : 1);
+ antenna = ((sc->ast_be_xmit / sc->sc_nbcnvaps) & 1 ? 2 : 1);
}
ds->ds_data = bf->bf_buf_addr;
@@ -128,8 +124,8 @@ static void ath_beacon_setup(struct ath_softc *sc,
/* NB: beacon's BufLen must be a multiple of 4 bytes */
ath9k_hw_filltxdesc(ah, ds
, roundup(skb->len, 4) /* buffer length */
- , AH_TRUE /* first segment */
- , AH_TRUE /* last segment */
+ , true /* first segment */
+ , true /* last segment */
, ds /* first descriptor */
);
@@ -219,7 +215,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
ASSERT(avp);
if (avp->av_bcbuf == NULL) {
- DPRINTF(sc, ATH_DEBUG_BEACON, "%s: avp=%p av_bcbuf=%p\n",
+ DPRINTF(sc, ATH_DBG_BEACON, "%s: avp=%p av_bcbuf=%p\n",
__func__, avp, avp->av_bcbuf);
return NULL;
}
@@ -272,9 +268,9 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
* the lock again which is a common function and that
* acquires txq lock inside.
*/
- if (sc->sc_nvaps > 1 && sc->sc_stagbeacons) {
- ath_tx_draintxq(sc, cabq, AH_FALSE);
- DPRINTF(sc, ATH_DEBUG_BEACON,
+ if (sc->sc_nvaps > 1) {
+ ath_tx_draintxq(sc, cabq, false);
+ DPRINTF(sc, ATH_DBG_BEACON,
"%s: flush previous cabq traffic\n", __func__);
}
}
@@ -309,7 +305,7 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id)
ASSERT(avp);
if (avp->av_bcbuf == NULL) {
- DPRINTF(sc, ATH_DEBUG_BEACON, "%s: avp=%p av_bcbuf=%p\n",
+ DPRINTF(sc, ATH_DBG_BEACON, "%s: avp=%p av_bcbuf=%p\n",
__func__, avp, avp != NULL ? avp->av_bcbuf : NULL);
return;
}
@@ -322,7 +318,7 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id)
/* NB: caller is known to have already stopped tx dma */
ath9k_hw_puttxbuf(ah, sc->sc_bhalq, bf->bf_daddr);
ath9k_hw_txstart(ah, sc->sc_bhalq);
- DPRINTF(sc, ATH_DEBUG_BEACON, "%s: TXDP%u = %llx (%p)\n", __func__,
+ DPRINTF(sc, ATH_DBG_BEACON, "%s: TXDP%u = %llx (%p)\n", __func__,
sc->sc_bhalq, ito64(bf->bf_daddr), bf->bf_desc);
}
@@ -377,7 +373,8 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
struct ath_buf, list);
list_del(&avp->av_bcbuf->list);
- if (sc->sc_opmode == HAL_M_HOSTAP || !sc->sc_hasveol) {
+ if (sc->sc_opmode == HAL_M_HOSTAP ||
+ !sc->sc_ah->ah_caps.halVEOLSupport) {
int slot;
/*
* Assign the vap to a beacon xmit slot. As
@@ -399,8 +396,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
avp->av_bslot = slot;
/* NB: keep looking for a double slot */
}
- KASSERT(sc->sc_bslot[avp->av_bslot] == ATH_IF_ID_ANY,
- ("beacon slot %u not empty?", avp->av_bslot));
+ BUG_ON(sc->sc_bslot[avp->av_bslot] != ATH_IF_ID_ANY);
sc->sc_bslot[avp->av_bslot] = if_id;
sc->sc_nbcnvaps++;
}
@@ -409,14 +405,10 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
/* release the previous beacon frame , if it already exists. */
bf = avp->av_bcbuf;
if (bf->bf_mpdu != NULL) {
- struct ath_xmit_status tx_status;
-
- skb = (struct sk_buff *) bf->bf_mpdu;
+ skb = (struct sk_buff *)bf->bf_mpdu;
ath_skb_unmap_single(sc, skb, PCI_DMA_TODEVICE,
get_dma_mem_context(bf, bf_dmacontext));
- tx_status.flags = 0;
- tx_status.retries = 0;
- ath_tx_complete(sc, skb, &tx_status, NULL);
+ dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
}
@@ -424,10 +416,12 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
* NB: the beacon data buffer must be 32-bit aligned;
* we assume the wbuf routines will return us something
* with this alignment (perhaps should assert).
+ * FIXME: Fill avp->av_boff.bo_tim,avp->av_btxctl.txpower and
+ * avp->av_btxctl.shortPreamble
*/
- skb = ath_get_beacon(sc, if_id, &avp->av_boff, &avp->av_btxctl);
+ skb = ieee80211_beacon_get(sc->hw, avp->av_if_data);
if (skb == NULL) {
- DPRINTF(sc, ATH_DEBUG_BEACON, "%s: cannot get skb\n",
+ DPRINTF(sc, ATH_DBG_BEACON, "%s: cannot get skb\n",
__func__);
return -ENOMEM;
}
@@ -438,8 +432,9 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
* of the beacon frame leaves the tstamp field immediately
* following the header.
*/
- if (sc->sc_stagbeacons && avp->av_bslot > 0) {
+ if (avp->av_bslot > 0) {
u_int64_t tsfadjust;
+ __le64 val;
int intval;
/* FIXME: Use default value for now: Sujith */
@@ -458,15 +453,15 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
* others get a timestamp aligned to the next interval.
*/
tsfadjust = (intval * (ATH_BCBUF - avp->av_bslot)) / ATH_BCBUF;
- tsfadjust = cpu_to_le64(tsfadjust<<10); /* TU->TSF */
+ val = cpu_to_le64(tsfadjust << 10); /* TU->TSF */
- DPRINTF(sc, ATH_DEBUG_BEACON,
+ DPRINTF(sc, ATH_DBG_BEACON,
"%s: %s beacons, bslot %d intval %u tsfadjust %llu\n",
- __func__, sc->sc_stagbeacons ? "stagger" : "burst",
+ __func__, "stagger",
avp->av_bslot, intval, (unsigned long long)tsfadjust);
wh = (struct ieee80211_hdr *)skb->data;
- memcpy(&wh[1], &tsfadjust, sizeof(tsfadjust));
+ memcpy(&wh[1], &val, sizeof(val));
}
bf->bf_buf_addr = ath_skb_map_single(sc, skb, PCI_DMA_TODEVICE,
@@ -495,14 +490,10 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp)
bf = avp->av_bcbuf;
if (bf->bf_mpdu != NULL) {
- struct sk_buff *skb = (struct sk_buff *) bf->bf_mpdu;
- struct ath_xmit_status tx_status;
-
+ struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
ath_skb_unmap_single(sc, skb, PCI_DMA_TODEVICE,
get_dma_mem_context(bf, bf_dmacontext));
- tx_status.flags = 0;
- tx_status.retries = 0;
- ath_tx_complete(sc, skb, &tx_status, NULL);
+ dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
}
list_add_tail(&bf->list, &sc->sc_bbuf);
@@ -527,13 +518,9 @@ void ath_beacon_free(struct ath_softc *sc)
list_for_each_entry(bf, &sc->sc_bbuf, list) {
if (bf->bf_mpdu != NULL) {
struct sk_buff *skb = (struct sk_buff *) bf->bf_mpdu;
- struct ath_xmit_status tx_status;
-
ath_skb_unmap_single(sc, skb, PCI_DMA_TODEVICE,
get_dma_mem_context(bf, bf_dmacontext));
- tx_status.flags = 0;
- tx_status.retries = 0;
- ath_tx_complete(sc, skb, &tx_status, NULL);
+ dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
}
}
@@ -562,6 +549,9 @@ void ath9k_beacon_tasklet(unsigned long data)
u_int32_t rx_clear = 0, rx_frame = 0, tx_frame = 0;
u_int32_t show_cycles = 0;
u_int32_t bc = 0; /* beacon count */
+ u_int64_t tsf;
+ u_int32_t tsftu;
+ u_int16_t intval;
if (sc->sc_noreset) {
show_cycles = ath9k_hw_GetMibCycleCountsPct(ah,
@@ -586,7 +576,7 @@ void ath9k_beacon_tasklet(unsigned long data)
*/
if (sc->sc_bmisscount < BSTUCK_THRESH) {
if (sc->sc_noreset) {
- DPRINTF(sc, ATH_DEBUG_BEACON,
+ DPRINTF(sc, ATH_DBG_BEACON,
"%s: missed %u consecutive beacons\n",
__func__, sc->sc_bmisscount);
if (show_cycles) {
@@ -596,19 +586,19 @@ void ath9k_beacon_tasklet(unsigned long data)
* stickiness.
*/
DPRINTF(sc,
- ATH_DEBUG_BEACON,
+ ATH_DBG_BEACON,
"%s: busy times: rx_clear=%d, "
"rx_frame=%d, tx_frame=%d\n",
__func__, rx_clear, rx_frame,
tx_frame);
} else {
DPRINTF(sc,
- ATH_DEBUG_BEACON,
+ ATH_DBG_BEACON,
"%s: unable to obtain "
"busy times\n", __func__);
}
} else {
- DPRINTF(sc, ATH_DEBUG_BEACON,
+ DPRINTF(sc, ATH_DBG_BEACON,
"%s: missed %u consecutive beacons\n",
__func__, sc->sc_bmisscount);
}
@@ -616,13 +606,13 @@ void ath9k_beacon_tasklet(unsigned long data)
if (sc->sc_noreset) {
if (sc->sc_bmisscount == BSTUCK_THRESH) {
DPRINTF(sc,
- ATH_DEBUG_BEACON,
+ ATH_DBG_BEACON,
"%s: beacon is officially "
"stuck\n", __func__);
ath9k_hw_dmaRegDump(ah);
}
} else {
- DPRINTF(sc, ATH_DEBUG_BEACON,
+ DPRINTF(sc, ATH_DBG_BEACON,
"%s: beacon is officially stuck\n",
__func__);
ath_bstuck_process(sc);
@@ -634,11 +624,11 @@ void ath9k_beacon_tasklet(unsigned long data)
if (sc->sc_bmisscount != 0) {
if (sc->sc_noreset) {
DPRINTF(sc,
- ATH_DEBUG_BEACON,
+ ATH_DBG_BEACON,
"%s: resume beacon xmit after %u misses\n",
__func__, sc->sc_bmisscount);
} else {
- DPRINTF(sc, ATH_DEBUG_BEACON,
+ DPRINTF(sc, ATH_DBG_BEACON,
"%s: resume beacon xmit after %u misses\n",
__func__, sc->sc_bmisscount);
}
@@ -646,55 +636,29 @@ void ath9k_beacon_tasklet(unsigned long data)
}
/*
- * Generate beacon frames. If we are sending frames
- * staggered then calculate the slot for this frame based
+ * Generate beacon frames. we are sending frames
+ * staggered so calculate the slot for this frame based
* on the tsf to safeguard against missing an swba.
- * Otherwise we are bursting all frames together and need
- * to generate a frame for each vap that is up and running.
*/
- if (sc->sc_stagbeacons) {
- /* staggered beacons */
- u_int64_t tsf;
- u_int32_t tsftu;
- u_int16_t intval;
- /* FIXME: Use default value for now - Sujith */
- intval = ATH_DEFAULT_BINTVAL;
+ /* FIXME: Use default value for now - Sujith */
+ intval = ATH_DEFAULT_BINTVAL;
- tsf = ath9k_hw_gettsf64(ah);
- tsftu = TSF_TO_TU(tsf>>32, tsf);
- slot = ((tsftu % intval) * ATH_BCBUF) / intval;
- if_id = sc->sc_bslot[(slot + 1) % ATH_BCBUF];
- DPRINTF(sc, ATH_DEBUG_BEACON,
+ tsf = ath9k_hw_gettsf64(ah);
+ tsftu = TSF_TO_TU(tsf>>32, tsf);
+ slot = ((tsftu % intval) * ATH_BCBUF) / intval;
+ if_id = sc->sc_bslot[(slot + 1) % ATH_BCBUF];
+ DPRINTF(sc, ATH_DBG_BEACON,
"%s: slot %d [tsf %llu tsftu %u intval %u] if_id %d\n",
__func__, slot, (unsigned long long) tsf, tsftu,
intval, if_id);
- bfaddr = 0;
- if (if_id != ATH_IF_ID_ANY) {
- bf = ath_beacon_generate(sc, if_id);
- if (bf != NULL) {
- bfaddr = bf->bf_daddr;
- bc = 1;
- }
+ bfaddr = 0;
+ if (if_id != ATH_IF_ID_ANY) {
+ bf = ath_beacon_generate(sc, if_id);
+ if (bf != NULL) {
+ bfaddr = bf->bf_daddr;
+ bc = 1;
}
- } else {
- /* XXX: Clean this up, move work to a helper */
- /* burst'd beacons */
- u_int32_t *bflink;
- bflink = &bfaddr;
- /* XXX rotate/randomize order? */
- for (slot = 0; slot < ATH_BCBUF; slot++) {
- if_id = sc->sc_bslot[slot];
- if (if_id != ATH_IF_ID_ANY) {
- bf = ath_beacon_generate(sc, if_id);
- if (bf != NULL) {
- *bflink = bf->bf_daddr;
- bflink = &bf->bf_desc->ds_link;
- bc++;
- }
- }
- }
- *bflink = 0; /* link of last frame */
}
/*
* Handle slot time change when a non-ERP station joins/leaves
@@ -719,27 +683,6 @@ void ath9k_beacon_tasklet(unsigned long data)
} else if (sc->sc_updateslot == COMMIT && sc->sc_slotupdate == slot)
ath_setslottime(sc); /* commit change to hardware */
- if ((!sc->sc_stagbeacons || slot == 0) && (!sc->sc_diversity)) {
- int otherant;
- /*
- * Check recent per-antenna transmit statistics and flip
- * the default rx antenna if noticeably more frames went out
- * on the non-default antenna. Only do this if rx diversity
- * is off.
- * XXX assumes 2 anntenae
- */
- otherant = sc->sc_defant & 1 ? 2 : 1;
- if (sc->sc_ant_tx[otherant] > sc->sc_ant_tx[sc->sc_defant] +
- ATH_ANTENNA_DIFF) {
- DPRINTF(sc, ATH_DEBUG_BEACON,
- "%s: flip defant to %u, %u > %u\n",
- __func__, otherant, sc->sc_ant_tx[otherant],
- sc->sc_ant_tx[sc->sc_defant]);
- ath_setdefantenna(sc, otherant);
- }
- sc->sc_ant_tx[1] = sc->sc_ant_tx[2] = 0;
- }
-
if (bfaddr != 0) {
/*
* Stop any current dma and put the new frame(s) on the queue.
@@ -747,7 +690,7 @@ void ath9k_beacon_tasklet(unsigned long data)
* are still pending on the queue.
*/
if (!ath9k_hw_stoptxdma(ah, sc->sc_bhalq)) {
- DPRINTF(sc, ATH_DEBUG_FATAL,
+ DPRINTF(sc, ATH_DBG_FATAL,
"%s: beacon queue %u did not stop?\n",
__func__, sc->sc_bhalq);
/* NB: the HAL still stops DMA, so proceed */
@@ -771,7 +714,7 @@ void ath9k_beacon_tasklet(unsigned long data)
void ath_bstuck_process(struct ath_softc *sc)
{
- DPRINTF(sc, ATH_DEBUG_BEACON,
+ DPRINTF(sc, ATH_DBG_BEACON,
"%s: stuck beacon; resetting (bmiss count %u)\n",
__func__, sc->sc_bmisscount);
ath_internal_reset(sc);
@@ -834,11 +777,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
*/
/* NB: the beacon interval is kept internally in TU's */
intval = conf.beacon_interval & HAL_BEACON_PERIOD;
- if (sc->sc_stagbeacons)
- intval /= ATH_BCBUF; /* for staggered beacons */
- if ((sc->sc_nostabeacons) &&
- (av_opmode == HAL_M_HOSTAP))
- nexttbtt = 0;
+ intval /= ATH_BCBUF; /* for staggered beacons */
} else {
intval = conf.beacon_interval & HAL_BEACON_PERIOD;
}
@@ -847,13 +786,10 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
nexttbtt = intval;
else if (intval) /* NB: can be 0 for monitor mode */
nexttbtt = roundup(nexttbtt, intval);
- DPRINTF(sc, ATH_DEBUG_BEACON, "%s: nexttbtt %u intval %u (%u)\n",
+ DPRINTF(sc, ATH_DBG_BEACON, "%s: nexttbtt %u intval %u (%u)\n",
__func__, nexttbtt, intval, conf.beacon_interval);
/* Check for HAL_M_HOSTAP and sc_nostabeacons for WDS client */
- if ((sc->sc_opmode == HAL_M_STA) ||
- ((sc->sc_opmode == HAL_M_HOSTAP) &&
- (av_opmode == HAL_M_STA) &&
- (sc->sc_nostabeacons))) {
+ if (sc->sc_opmode == HAL_M_STA) {
struct hal_beacon_state bs;
u_int64_t tsf;
u_int32_t tsftu;
@@ -936,7 +872,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
if (bs.bs_sleepduration > bs.bs_dtimperiod)
bs.bs_sleepduration = bs.bs_dtimperiod;
- DPRINTF(sc, ATH_DEBUG_BEACON,
+ DPRINTF(sc, ATH_DBG_BEACON,
"%s: tsf %llu "
"tsf:tu %u "
"intval %u "
@@ -963,12 +899,10 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
, bs.bs_timoffset
);
- if (!(sc->sc_nostabeacons)) {
- ath9k_hw_set_interrupts(ah, 0);
- ath9k_hw_set_sta_beacon_timers(ah, &bs);
- sc->sc_imask |= HAL_INT_BMISS;
- ath9k_hw_set_interrupts(ah, sc->sc_imask);
- }
+ ath9k_hw_set_interrupts(ah, 0);
+ ath9k_hw_set_sta_beacon_timers(ah, &bs);
+ sc->sc_imask |= HAL_INT_BMISS;
+ ath9k_hw_set_interrupts(ah, sc->sc_imask);
} else {
u_int64_t tsf;
u_int32_t tsftu;
@@ -990,7 +924,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
} while (nexttbtt < tsftu);
}
#undef FUDGE
- DPRINTF(sc, ATH_DEBUG_BEACON,
+ DPRINTF(sc, ATH_DBG_BEACON,
"%s: IBSS nexttbtt %u intval %u (%u)\n",
__func__, nexttbtt,
intval & ~HAL_BEACON_RESET_TSF,
@@ -1004,7 +938,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
* deal with things.
*/
intval |= HAL_BEACON_ENA;
- if (!sc->sc_hasveol)
+ if (!ah->ah_caps.halVEOLSupport)
sc->sc_imask |= HAL_INT_SWBA;
ath_beaconq_config(sc);
} else if (sc->sc_opmode == HAL_M_HOSTAP) {
@@ -1023,7 +957,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
* When using a self-linked beacon descriptor in
* ibss mode load it once here.
*/
- if (sc->sc_opmode == HAL_M_IBSS && sc->sc_hasveol)
+ if (sc->sc_opmode == HAL_M_IBSS && ah->ah_caps.halVEOLSupport)
ath_beacon_start_adhoc(sc, 0);
}
#undef TSF_TO_TU