56#include <sys/sysctl.h>
58#include <sys/malloc.h>
61#include <sys/kernel.h>
62#include <sys/socket.h>
63#include <sys/sockio.h>
65#include <sys/callout.h>
67#include <sys/endian.h>
68#include <sys/kthread.h>
69#include <sys/taskqueue.h>
71#include <sys/module.h>
75#include <machine/bus.h>
78#include <net/if_var.h>
80#include <net/if_media.h>
81#include <net/if_types.h>
82#include <net/if_arp.h>
83#include <net/ethernet.h>
84#include <net/if_llc.h>
86#include <net80211/ieee80211_var.h>
87#include <net80211/ieee80211_regdomain.h>
88#ifdef IEEE80211_SUPPORT_SUPERG
89#include <net80211/ieee80211_superg.h>
95#include <netinet/in.h>
96#include <netinet/if_ether.h>
107#include <dev/ath/ath_tx99/ath_tx99.h>
119 memset(&qi, 0,
sizeof(qi));
138#define ATH_EXPONENT_TO_VALUE(v) ((1<<(v))-1)
139 struct ieee80211com *ic = &sc->
sc_ic;
144 if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
145 ic->ic_opmode == IEEE80211_M_MBSS) {
153 struct chanAccParams chp;
154 struct wmeParams *wmep;
156 ieee80211_wme_ic_getparams(ic, &chp);
157 wmep = &chp.cap_wmeParams[WME_AC_BE];
168 device_printf(sc->
sc_dev,
"unable to update parameters for "
169 "beacon hardware queue!\n");
175#undef ATH_EXPONENT_TO_VALUE
184 struct ieee80211vap *vap = ni->ni_vap;
191 DPRINTF(sc, ATH_DEBUG_NODE,
"%s: bf_m=%p, bf_node=%p\n",
193 if (bf->
bf_m != NULL) {
199 ieee80211_free_node(bf->
bf_node);
208 m = ieee80211_beacon_alloc(ni);
210 device_printf(sc->
sc_dev,
"%s: cannot get mbuf\n", __func__);
219 "%s: cannot map mbuf, bus_dmamap_load_mbuf_sg returns %d\n",
233 struct ieee80211_frame *wh;
245 tsfadjust = ni->ni_intval *
247 tsfadjust = htole64(tsfadjust << 10);
250 "%s: %s beacons bslot %d intval %u tsfadjust %llu\n",
253 (
long long unsigned) le64toh(tsfadjust));
255 wh = mtod(m,
struct ieee80211_frame *);
256 memcpy(&wh[1], &tsfadjust,
sizeof(tsfadjust));
259 bf->
bf_node = ieee80211_ref_node(ni);
270#define USE_SHPREAMBLE(_ic) \
271 (((_ic)->ic_flags & (IEEE80211_F_SHPREAMBLE | IEEE80211_F_USEBARKER))\
272 == IEEE80211_F_SHPREAMBLE)
273 struct ieee80211_node *ni = bf->
bf_node;
274 struct ieee80211com *ic = ni->ni_ic;
275 struct mbuf *m = bf->
bf_m;
282 uint32_t segLenList[4];
285 DPRINTF(sc, ATH_DEBUG_BEACON_PROC,
"%s: m %p len %u\n",
286 __func__, m, m->m_len);
294 if (ic->ic_opmode == IEEE80211_M_IBSS && sc->
sc_hasveol) {
317 (
"multi-segment beacon frame; nseg %u", bf->
bf_nseg));
330 ,
sizeof(
struct ieee80211_frame)
332 , ieee80211_get_node_txpower(ni)
347 memset(&rc, 0,
sizeof(rc));
361 segLenList[0] =
roundup(m->m_len, 4);
362 segLenList[1] = segLenList[2] = segLenList[3] = 0;
363 bufAddrList[0] = bf->
bf_segs[0].ds_addr;
364 bufAddrList[1] = bufAddrList[2] = bufAddrList[3] = 0;
383 struct ieee80211_beacon_offsets *bo = &vap->iv_bcn_off;
385 setbit(bo->bo_flags, item);
398 bzero(&hs,
sizeof(hs));
415 "%s: valid=%d, txbusy=%u, rxbusy=%u, chanbusy=%u, "
416 "extchanbusy=%u, cyclecount=%u\n",
436 struct ieee80211vap *vap;
441 DPRINTF(sc, ATH_DEBUG_BEACON_PROC,
"%s: pending %u\n",
457 "%s: missed %u consecutive beacons\n",
465 "%s: resume beacon xmit after %u misses\n",
475 struct ieee80211com *ic = &sc->
sc_ic;
480 slot = ((tsftu % ic->ic_lintval) *
ATH_BCBUF) / ic->ic_lintval;
483 if (vap != NULL && vap->iv_state >= IEEE80211_S_RUN) {
489 uint32_t *bflink = &bfaddr;
491 for (slot = 0; slot <
ATH_BCBUF; slot++) {
493 if (vap != NULL && vap->iv_state >= IEEE80211_S_RUN) {
556 "%s: beacon queue %u did not stop?\n",
581 if (TAILQ_EMPTY(&cabq->axq_q))
583 bf = TAILQ_FIRST(&cabq->axq_q);
584 bf_last = TAILQ_LAST(&cabq->axq_q, axq_q_s);
612 "%s: Q%d: CAB FIFO queue=%d?\n",
632 TAILQ_FOREACH(bfi, &cabq->axq_q, bf_list) {
633 ath_printtxbuf(sc, bf, cabq->
axq_qnum, i, 0);
644 TAILQ_CONCAT(&cabq->
fifo.axq_q, &cabq->axq_q, bf_list);
668 if (TAILQ_EMPTY(&cabq->axq_q))
670 bf = TAILQ_FIRST(&cabq->axq_q);
691 if (TAILQ_EMPTY(&cabq->axq_q))
709 KASSERT(vap->iv_state >= IEEE80211_S_RUN,
710 (
"not running, state %d", vap->iv_state));
711 KASSERT(avp->
av_bcbuf != NULL, (
"no beacon buffer"));
724 if (ieee80211_beacon_update(bf->
bf_node, m, nmcastq)) {
731 if_printf(vap->iv_ifp,
732 "%s: bus_dmamap_load_mbuf_sg failed, error %u\n",
737 if ((vap->iv_bcn_off.bo_tim[4] & 1) && cabq->
axq_depth) {
739 "%s: cabq did not drain, mcastq %u cabq %u\n",
781 if (vap->iv_bcn_off.bo_tim[4] & 1) {
785 struct ath_buf *bfm, *bfc_last;
796 bfm = TAILQ_FIRST(&avp->
av_mcastq.axq_q);
807 if (bfc_last != NULL) {
835 KASSERT(avp->
av_bcbuf != NULL, (
"no beacon buffer"));
845 if (ieee80211_beacon_update(bf->
bf_node, m, 0)) {
852 if_printf(vap->iv_ifp,
853 "%s: bus_dmamap_load_mbuf_sg failed, error %u\n",
873 DPRINTF(sc, ATH_DEBUG_NODE,
"%s: free bf=%p, bf_m=%p, bf_node=%p\n",
875 if (bf->
bf_m != NULL) {
881 ieee80211_free_node(bf->
bf_node);
884 TAILQ_INSERT_TAIL(&sc->
sc_bbuf, bf, bf_list);
895 TAILQ_FOREACH(bf, &sc->
sc_bbuf, bf_list) {
897 "%s: free bf=%p, bf_m=%p, bf_node=%p\n",
899 if (bf->
bf_m != NULL) {
905 ieee80211_free_node(bf->
bf_node);
929#define TSF_TO_TU(_h,_l) \
930 ((((u_int32_t)(_h)) << 22) | (((u_int32_t)(_l)) >> 10))
934 struct ieee80211com *ic = &sc->
sc_ic;
935 struct ieee80211_node *ni;
936 u_int32_t nexttbtt, intval, tsftu;
937 u_int32_t nexttbtt_u8, intval_u8;
938 u_int64_t tsf, tsf_beacon;
950 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
952 if ((vap->iv_opmode == IEEE80211_M_STA) &&
953 ((vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS) != 0))
957 IEEE80211_UNLOCK(ic);
961 device_printf(sc->
sc_dev,
"called with no valid vaps?\n");
965 if ((vap->iv_flags_ext & IEEE80211_FEXT_SWBMISS) != 0) {
966 device_printf(sc->
sc_dev,
"called on VAP with SWBMISS set?\n");
973 ni = ieee80211_ref_node(vap->iv_bss);
984 nexttbtt =
TSF_TO_TU(le32dec(ni->ni_tstamp.data + 4),
985 le32dec(ni->ni_tstamp.data));
987 tsf_beacon = ((uint64_t) le32dec(ni->ni_tstamp.data + 4)) << 32;
988 tsf_beacon |= le32dec(ni->ni_tstamp.data);
990 if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
991 ic->ic_opmode == IEEE80211_M_MBSS) {
1025 nexttbtt =
roundup(nexttbtt, intval);
1028 if (ic->ic_opmode == IEEE80211_M_STA && !sc->
sc_swbmiss) {
1030 int dtimperiod, dtimcount;
1031 int cfpperiod, cfpcount;
1037 dtimperiod = ni->ni_dtim_period;
1038 if (dtimperiod <= 0)
1040 dtimcount = ni->ni_dtim_count;
1041 if (dtimcount >= dtimperiod)
1053 "%s: beacon tsf=%llu, hw tsf=%llu, nexttbtt=%u, tsftu=%u\n",
1055 (
unsigned long long) tsf_beacon,
1056 (
unsigned long long) tsf,
1060 "%s: beacon tsf=%llu, hw tsf=%llu, tsf delta=%lld\n",
1062 (
unsigned long long) tsf_beacon,
1063 (
unsigned long long) tsf,
1065 (
long long) tsf_beacon);
1068 "%s: nexttbtt=%llu, beacon tsf delta=%lld\n",
1070 (
unsigned long long) nexttbtt,
1071 (
long long) ((
long long) nexttbtt * 1024LL) - (
long long) tsf_beacon);
1075 if (nexttbtt > tsftu) {
1076 uint32_t countdiff, oldtbtt, remainder;
1079 remainder = (nexttbtt - tsftu) % intval;
1080 nexttbtt = tsftu + remainder;
1082 countdiff = (oldtbtt - nexttbtt) / intval % dtimperiod;
1083 if (dtimcount > countdiff) {
1084 dtimcount -= countdiff;
1086 dtimcount += dtimperiod - countdiff;
1089 uint32_t countdiff, oldtbtt, remainder;
1092 remainder = (tsftu - nexttbtt) % intval;
1093 nexttbtt = tsftu - remainder + intval;
1094 countdiff = (nexttbtt - oldtbtt) / intval % dtimperiod;
1095 if (dtimcount > countdiff) {
1096 dtimcount -= countdiff;
1098 dtimcount += dtimperiod - countdiff;
1103 "%s: adj nexttbtt=%llu, rx tsf delta=%lld\n",
1105 (
unsigned long long) nexttbtt,
1106 (
long long) ((
long long)nexttbtt * 1024LL) - (
long long)tsf);
1108 memset(&bs, 0,
sizeof(bs));
1154 "%s: tsf %ju tsf:tu %u intval %u nexttbtt %u dtim %u "
1155 "nextdtim %u bmiss %u sleep %u cfp:period %u "
1156 "maxdur %u next %u timoffset %u\n"
1177 if (nexttbtt == intval)
1179 if (ic->ic_opmode == IEEE80211_M_IBSS) {
1199 }
while (nexttbtt < tsftu);
1202 }
else if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
1203 ic->ic_opmode == IEEE80211_M_MBSS) {
1233 if (ic->ic_opmode == IEEE80211_M_IBSS && sc->
sc_hasveol)
1236 ieee80211_free_node(ni);
1240 "%s: nexttbtt %u intval %u (%u), tsf64=%llu tsfbeacon=%llu delta=%lld\n",
1241 __func__, nexttbtt, intval, ni->ni_intval,
1242 (
unsigned long long) tsf,
1243 (
unsigned long long) tsf_beacon,
1245 (
long long) tsf_beacon);
uint16_t ath_hal_computetxtime(struct ath_hal *ah, const HAL_RATE_TABLE *rates, uint32_t frameLen, uint16_t rateix, HAL_BOOL shortPreamble, HAL_BOOL includeSifs)
#define HAL_BEACON_PERIOD
#define HAL_BEACON_PERIOD_TU8
@ HAL_TXQ_TXDESCINT_ENABLE
@ HAL_TXQ_TXERRINT_ENABLE
#define HAL_BEACON_RESET_TSF
#define HAL_TXQ_USEDEFAULT
#define HAL_TXKEYIX_INVALID
#define IEEE80211_CRC_LEN
int ath_hal_gethangstate(struct ath_hal *ah, uint32_t mask, uint32_t *hangs)
void ath_setslottime(struct ath_softc *sc)
void ath_tx_draintxq(struct ath_softc *sc, struct ath_txq *txq)
void ath_setdefantenna(struct ath_softc *sc, u_int antenna)
void ath_txqmove(struct ath_txq *dst, struct ath_txq *src)
#define ATH_ALQ_RESUME_BEACON
static int if_ath_alq_checkdebug(struct if_ath_alq *alq, uint16_t op)
void if_ath_alq_post(struct if_ath_alq *alq, uint16_t op, uint16_t len, const char *buf)
#define ATH_ALQ_MISSED_BEACON
void ath_beacon_config(struct ath_softc *sc, struct ieee80211vap *vap)
void ath_beacon_update(struct ieee80211vap *vap, int item)
void ath_beacon_miss(struct ath_softc *sc)
struct ath_buf * ath_beacon_generate(struct ath_softc *sc, struct ieee80211vap *vap)
#define TSF_TO_TU(_h, _l)
void ath_beacon_free(struct ath_softc *sc)
#define USE_SHPREAMBLE(_ic)
void ath_beacon_cabq_start(struct ath_softc *sc)
static void ath_beacon_cabq_start_edma(struct ath_softc *sc)
int ath_beaconq_setup(struct ath_softc *sc)
int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_node *ni)
void ath_beacon_start_adhoc(struct ath_softc *sc, struct ieee80211vap *vap)
static void ath_beacon_setup(struct ath_softc *sc, struct ath_buf *bf)
void ath_beacon_return(struct ath_softc *sc, struct ath_buf *bf)
int ath_beaconq_config(struct ath_softc *sc)
static void ath_beacon_cabq_start_legacy(struct ath_softc *sc)
#define ATH_EXPONENT_TO_VALUE(v)
void ath_beacon_proc(void *arg, int pending)
#define DPRINTF(sc, m, fmt,...)
#define ath_power_restore_power_state(sc)
#define ath_power_set_power_state(sc, ps)
#define ath_hal_beaconinit(_ah, _nextb, _bperiod)
#define ATH_BEACON_CWMAX_DEFAULT
#define ath_hal_puttxbuf(_ah, _q, _bufaddr)
#define ath_hal_numtxpending(_ah, _q)
#define ath_hal_gettxqueueprops(_ah, _q, _qi)
#define ath_hal_gettsf32(_ah)
#define ath_hal_settxqueueprops(_ah, _q, _qi)
#define ATH_TXQ_LAST(_tq, _field)
#define ATH_TXQ_LOCK_ASSERT(_tq)
#define ath_hal_setuptxdesc(_ah, _ds, _plen, _hlen, _atype, _txpow, _txr0, _txtr0, _keyix, _ant, _flags, _rtsrate, _rtsdura)
#define ath_hal_get_mib_cycle_counts(_ah, _sample)
#define ATH_TXQ_PUTRUNNING
#define ath_hal_intrset(_ah, _mask)
#define ATH_BEACON_CWMIN_DEFAULT
#define ATH_TXQ_LOCK(_tq)
#define ath_hal_set_quiet(_ah, _p, _d, _o, _f)
#define ATH_TXQ_UNLOCK(_tq)
#define ath_hal_gettsf64(_ah)
#define ath_hal_stoptxdma(_ah, _qnum)
#define ath_hal_settxdesclink(_ah, _ds, _link)
#define ath_hal_filltxdesc(_ah, _ds, _b, _l, _did, _qid, _first, _last, _ds0)
#define ath_hal_resettxqueue(_ah, _q)
#define ath_hal_beacontimers(_ah, _bs)
#define ath_hal_gettxdesclinkptr(_ah, _ds, _linkptr)
#define ath_hal_setuptxqueue(_ah, _type, _irq)
#define ATH_BEACON_AIFS_DEFAULT
#define ath_hal_set11nratescenario(_ah, _ds, _dur, _rt, _series, _ns, _flags)
#define ath_hal_txstart(_ah, _q)
uint16_t bs_cfpmaxduration
uint32_t bs_sleepduration
uint16_t bs_bmissthreshold
struct HAL_RATE_TABLE::@3 info[64]
HAL_TX_QUEUE_FLAGS tqi_qflags
struct ath_desc * bf_lastds
struct ath_desc * bf_desc
bus_dma_segment_t bf_segs[ATH_MAX_SCATTER]
struct ieee80211_node * bf_node
const HAL_RATE_TABLE * sc_currates
struct ath_stats sc_stats
struct ieee80211vap * sc_bslot[ATH_BCBUF]
enum ath_softc::@35 sc_updateslot
struct task sc_bstucktask
u_int32_t sc_ant_tx[ATH_IOCTL_STATS_NUM_TX_ANTENNA]
struct ieee80211com sc_ic
struct ieee80211_quiet_ie quiet_ie
struct ath_buf * av_bcbuf