49#include <sys/sysctl.h>
51#include <sys/malloc.h>
54#include <sys/kernel.h>
55#include <sys/socket.h>
56#include <sys/sockio.h>
58#include <sys/callout.h>
60#include <sys/endian.h>
61#include <sys/kthread.h>
62#include <sys/taskqueue.h>
66#include <machine/bus.h>
69#include <net/if_var.h>
71#include <net/if_media.h>
72#include <net/if_types.h>
73#include <net/if_arp.h>
74#include <net/ethernet.h>
75#include <net/if_llc.h>
77#include <net80211/ieee80211_var.h>
78#include <net80211/ieee80211_regdomain.h>
79#ifdef IEEE80211_SUPPORT_SUPERG
80#include <net80211/ieee80211_superg.h>
82#ifdef IEEE80211_SUPPORT_TDMA
83#include <net80211/ieee80211_tdma.h>
85#include <net80211/ieee80211_ht.h>
90#include <netinet/in.h>
91#include <netinet/if_ether.h>
101#include <dev/ath/ath_tx99/ath_tx99.h>
115#define SWMAX_RETRIES 10
120#define ATH_NONQOS_TID_AC WME_AC_VO
130 struct ieee80211_node *ni,
struct ath_buf *bf,
struct mbuf *m0);
132 struct ieee80211_node *ni,
struct mbuf *m0,
int *tid);
153 for (i = 0, ds = (
const char *) bf->
bf_desc;
185 const struct ieee80211_frame *wh;
187 wh = mtod(m0,
const struct ieee80211_frame *);
190 if (! IEEE80211_QOS_HAS_SEQ(wh))
191 return (WME_AC_TO_TID(M_WME_GETAC(m0)));
194 return (ieee80211_gettid(wh));
200 struct ieee80211_frame *wh;
202 wh = mtod(bf->
bf_m,
struct ieee80211_frame *);
205 wh->i_fc[1] |= IEEE80211_FC1_RETRY;
207 BUS_DMASYNC_PREWRITE);
237 const struct ieee80211_frame *wh;
239 wh = mtod(m0,
const struct ieee80211_frame *);
246 if (IEEE80211_QOS_HAS_SEQ(wh))
247 return TID_TO_WME_AC(ieee80211_gettid(wh));
252 return (M_WME_GETAC(m0));
257 ath_bufhead *frags,
struct ieee80211_node *ni)
263 TAILQ_FOREACH_SAFE(bf, frags, bf_list, next) {
265 TAILQ_REMOVE(frags, bf, bf_list);
267 ieee80211_node_decref(ni);
278 struct mbuf *m0,
struct ieee80211_node *ni)
284 for (m = m0->m_nextpkt; m != NULL; m = m->m_nextpkt) {
288 DPRINTF(sc, ATH_DEBUG_XMIT,
"%s: no buffer?\n",
293 ieee80211_node_incref(ni);
294 TAILQ_INSERT_TAIL(frags, bf, bf_list);
298 return !TAILQ_EMPTY(frags);
314 if (error == EFBIG) {
317 }
else if (error != 0) {
319 ieee80211_free_mbuf(m0);
331 ieee80211_free_mbuf(m0);
341 ieee80211_free_mbuf(m0);
345 (
"too many segments after defrag; nseg %u", bf->
bf_nseg));
348 ieee80211_free_mbuf(m0);
351 DPRINTF(sc, ATH_DEBUG_XMIT,
"%s: m %p len %u\n",
352 __func__, m0, m0->m_pkthdr.len);
366 struct ath_buf *bf,
bool is_aggr,
int is_first_subframe,
367 int is_last_subframe)
373 uint32_t segLenList[4];
400 bzero(bufAddrList,
sizeof(bufAddrList));
401 bzero(segLenList,
sizeof(segLenList));
402 for (i = 0; i < bf->
bf_nseg; i++) {
403 bufAddrList[bp] = bf->
bf_segs[i].ds_addr;
404 segLenList[bp] = bf->
bf_segs[i].ds_len;
411 if ((i != bf->
bf_nseg - 1) && (bp < numTxMaps))
457 if (is_last_subframe) {
460 }
else if (is_aggr) {
485 bzero(bufAddrList,
sizeof(bufAddrList));
486 bzero(segLenList,
sizeof(segLenList));
554 struct ath_buf *bf, *bf_prev = NULL;
557 DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR,
"%s: nframes=%d, al=%d\n",
564 DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR,
"%s: bf=%p, txrate0=%d\n",
567 DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR,
"%s: bf=%p, rix0=%d\n",
575 DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR,
576 "%s: bf=%p, nseg=%d, pktlen=%d, seqno=%d\n",
602 if (bf == bf_first) {
619 if (bf == bf_first) {
681 DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR,
"%s: end\n", __func__);
705 (
"%s: busy status 0x%x", __func__, bf->
bf_flags));
713 "%s: bf=%p, bfs_tx_queue=%d, axq_qnum=%d\n",
721 struct ieee80211_frame *wh;
724 wh = mtod(bf_last->
bf_m,
struct ieee80211_frame *);
725 wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA;
727 BUS_DMASYNC_PREWRITE);
758 (
"%s: busy status 0x%x", __func__, bf->
bf_flags));
760 (
"ath_tx_handoff_hw called for mcast queue"));
769 "%s: TX dispatch without holding txcount/txstart refcnt!\n",
806 "ath_tx_handoff: non-tdma: txq=%u, add bf=%p "
821 "%s: link[%u](%p)=%p (%p) depth %d\n", __func__,
826 "ath_tx_handoff: non-tdma: link[%u](%p)=%p (%p) "
845 bf_first = TAILQ_FIRST(&txq->axq_q);
849 "%s: TXDP[%u] = %p (%p) depth %d\n",
854 "ath_tx_handoff: TXDP[%u] = %p (%p) "
855 "lastds=%p depth %d",
868 "%s: bf=%p, bfs_tx_queue=%d, axq_qnum=%d\n",
902 "ath_tx_handoff: txq=%u, txstart", txq->
axq_qnum);
918 bf = TAILQ_FIRST(&txq->axq_q);
925 "%s: Q%d: bf=%p, bf_last=%p, daddr=0x%08x\n",
942 (
"%s: Q%d: called with PUTRUNNING=1\n",
967 ath_tx_alq_post(sc, bf);
978 struct mbuf *m0,
int iswep,
int isfrag,
int *hdrlen,
int *pktlen,
982 "%s: hdrlen=%d, pktlen=%d, isfrag=%d, iswep=%d, m0=%p\n",
991 const struct ieee80211_cipher *cip;
992 struct ieee80211_key *k;
999 k = ieee80211_crypto_encap(ni, m0);
1018 (*hdrlen) += cip->ic_header;
1019 (*pktlen) += cip->ic_header + cip->ic_trailer;
1021 if ((k->wk_flags & IEEE80211_KEY_SWMIC) == 0 && !isfrag)
1022 (*pktlen) += cip->ic_miclen;
1023 (*keyix) = k->wk_keyix;
1024 }
else if (ni->ni_ucastkey.wk_cipher == &ieee80211_cipher_none) {
1028 (*keyix) = ni->ni_ucastkey.wk_keyix;
1029 if ((*keyix) == IEEE80211_KEYIX_NONE)
1048 struct ieee80211_frame *wh;
1053 struct ieee80211com *ic = &sc->
sc_ic;
1058 wh = mtod(bf->
bf_m,
struct ieee80211_frame *);
1073 if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
1074 rt->
info[rix].
phy == IEEE80211_T_OFDM &&
1078 if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) {
1080 }
else if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
1101 if ((ic->ic_htprotmode == IEEE80211_PROT_RTSCTS) &&
1102 rt->
info[rix].
phy == IEEE80211_T_HT &&
1121 struct ieee80211_frame *wh;
1127 int isfrag = bf->
bf_m->m_flags & M_FRAG;
1132 wh = mtod(bf->
bf_m,
struct ieee80211_frame *);
1139 (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_CTL) {
1145 if (wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG) {
1174 *(u_int16_t *)wh->i_dur = htole16(dur);
1180 int cix,
int shortPreamble)
1190 KASSERT(cix != 0xff, (
"cix not setup"));
1208 int ctsduration = 0;
1211 if (rt->
info[cix].
phy == IEEE80211_T_HT) {
1212 printf(
"%s: HT rate where it shouldn't be (0x%x)\n",
1226 if (shortPreamble) {
1242 return (ctsduration);
1261 uint16_t ctsduration = 0;
1262 uint8_t ctsrate = 0;
1338 "%s: bf=%p, txrate0=%d\n", __func__, bf, 0);
1380 int pktlen,
int is_aggr)
1395 pktlen, tid, is_aggr, &rix, &try0, &rate, &maxdur, &maxpktlen);
1445 struct mbuf *m0,
int *queue_to_head)
1447 struct ieee80211_node *ni = &an->
an_node;
1448 struct ieee80211_frame *wh;
1449 uint8_t type, subtype;
1451 wh = mtod(m0,
struct ieee80211_frame *);
1452 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1453 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
1455 (*queue_to_head) = 0;
1458 if ((
ATH_NODE(ni)->an_is_powersave == 0)
1459 && type == IEEE80211_FC0_TYPE_CTL &&
1460 subtype == IEEE80211_FC0_SUBTYPE_BAR) {
1462 "%s: BAR: TX'ing direct\n", __func__);
1464 }
else if ((
ATH_NODE(ni)->an_is_powersave == 1)
1465 && type == IEEE80211_FC0_TYPE_CTL &&
1466 subtype == IEEE80211_FC0_SUBTYPE_BAR) {
1469 "%s: swq: TX'ing\n", __func__);
1470 (*queue_to_head) = 1;
1472 }
else if ((
ATH_NODE(ni)->an_is_powersave == 1)
1473 && (type == IEEE80211_FC0_TYPE_MGT ||
1474 type == IEEE80211_FC0_TYPE_CTL)) {
1480 "%s: %6D: Node is asleep; sending mgmt "
1481 "(type=%d, subtype=%d)\n",
1482 __func__, ni->ni_macaddr,
":", type, subtype);
1558 struct ieee80211vap *vap = ni->ni_vap;
1559 struct ieee80211com *ic = &sc->
sc_ic;
1560 int error, iswep, ismcast, isfrag, ismrr;
1561 int keyix, hdrlen, pktlen, try0 = 0;
1562 u_int8_t rix = 0, txrate = 0;
1564 struct ieee80211_frame *wh;
1565 u_int subtype, flags;
1583 wh = mtod(m0,
struct ieee80211_frame *);
1584 iswep = wh->i_fc[1] & IEEE80211_FC1_PROTECTED;
1585 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
1586 isfrag = m0->m_flags & M_FRAG;
1587 hdrlen = ieee80211_anyhdrsize(wh);
1592 pktlen = m0->m_pkthdr.len - (hdrlen & 3);
1597 ieee80211_free_mbuf(m0);
1602 wh = mtod(m0,
struct ieee80211_frame *);
1613 KASSERT((ni != NULL), (
"%s: ni=NULL!", __func__));
1616 wh = mtod(m0,
struct ieee80211_frame *);
1621 KASSERT(rt != NULL, (
"no rate table, mode %u", sc->
sc_curmode));
1628 if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
1629 (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE)) {
1647 switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
1648 case IEEE80211_FC0_TYPE_MGT:
1649 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
1650 if (subtype == IEEE80211_FC0_SUBTYPE_BEACON)
1652 else if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)
1654 else if (subtype == IEEE80211_FC0_SUBTYPE_ATIM)
1665 case IEEE80211_FC0_TYPE_CTL:
1674 case IEEE80211_FC0_TYPE_DATA:
1687 }
else if (m0->m_flags & M_EAPOL) {
1706 if (ieee80211_wme_vap_ac_is_noack(vap, pri))
1710 device_printf(sc->
sc_dev,
"bogus frame type 0x%x (%s)\n",
1711 wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK, __func__);
1714 ieee80211_free_mbuf(m0);
1740 if (txq != sc->
sc_ac2q[pri]) {
1742 "%s: txq=%p (%d), pri=%d, pri txq=%p (%d)\n",
1757 }
else if (pktlen > vap->iv_rtsthreshold &&
1758 (ni->ni_ath_flags & IEEE80211_NODE_FF) == 0) {
1764#ifdef IEEE80211_SUPPORT_TDMA
1767 "%s: discard frame, ACK required w/ TDMA\n", __func__);
1770 ieee80211_free_mbuf(m0);
1779 if (ieee80211_get_toa_params(m0, NULL)) {
1780 device_printf(sc->
sc_dev,
1781 "%s: setting TX positioning bit\n", __func__);
1841 m0->m_nextpkt = NULL;
1844 ieee80211_dump_pkt(ic, mtod(m0,
const uint8_t *), m0->m_len,
1847 if (ieee80211_radiotap_active_vap(vap)) {
1857 ieee80211_radiotap_tx(vap, m0);
1905 struct ath_buf *bf,
struct mbuf *m0)
1907 struct ieee80211vap *vap = ni->ni_vap;
1914 const struct ieee80211_frame *wh;
1915 int is_ampdu, is_ampdu_tx, is_ampdu_pending;
1916 ieee80211_seq seqno;
1917 uint8_t type, subtype;
1951 wh = mtod(m0,
struct ieee80211_frame *);
1952 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
1953 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1954 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
1961 if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
1987 if (type == IEEE80211_FC0_TYPE_DATA &&
1999 is_ampdu = is_ampdu_tx | is_ampdu_pending;
2001 DPRINTF(sc, ATH_DEBUG_SW_TX,
"%s: tid=%d, ac=%d, is_ampdu=%d\n",
2002 __func__, tid, pri, is_ampdu);
2041 if (is_ampdu_tx && (! IEEE80211_IS_MULTICAST(wh->i_addr1))) {
2054 if (IEEE80211_QOS_HAS_SEQ(wh) &&
2055 (! IEEE80211_IS_MULTICAST(wh->i_addr1)) &&
2056 (subtype != IEEE80211_FC0_SUBTYPE_QOS_NULL)) {
2068 if (is_ampdu_pending)
2070 "%s: tid %d: ampdu pending, seqno %d\n",
2071 __func__, tid, M_SEQNO_GET(m0));
2110 "%s: bf=%p: mcastq: TX'ing\n", __func__, bf);
2140 struct ath_buf *bf,
struct mbuf *m0,
2141 const struct ieee80211_bpf_params *params)
2143 struct ieee80211com *ic = &sc->
sc_ic;
2144 struct ieee80211vap *vap = ni->ni_vap;
2145 int error, ismcast, ismrr;
2146 int keyix, hdrlen, pktlen, try0, txantenna;
2147 u_int8_t rix, txrate;
2148 struct ieee80211_frame *wh;
2156 uint8_t type, subtype;
2162 wh = mtod(m0,
struct ieee80211_frame *);
2163 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
2164 hdrlen = ieee80211_anyhdrsize(wh);
2172 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
2173 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
2176 "ath_tx_raw_start: ni=%p, bf=%p, raw", ni, bf);
2178 DPRINTF(sc, ATH_DEBUG_SW_TX,
"%s: ismcast=%d\n",
2181 pri = params->ibp_pri & 3;
2183 if (! IEEE80211_QOS_HAS_SEQ(wh))
2193 "%s: overriding tid %d pri %d -> %d\n",
2194 __func__, o_tid, pri, TID_TO_WME_AC(o_tid));
2196 pri = TID_TO_WME_AC(o_tid);
2209 m0, params->ibp_flags & IEEE80211_BPF_CRYPTO, 0,
2210 &hdrlen, &pktlen, &keyix)) {
2211 ieee80211_free_mbuf(m0);
2215 wh = mtod(m0,
struct ieee80211_frame *);
2225 wh = mtod(m0,
struct ieee80211_frame *);
2226 KASSERT((ni != NULL), (
"%s: ni=NULL!", __func__));
2232 if (params->ibp_flags & IEEE80211_BPF_RTS)
2234 else if (params->ibp_flags & IEEE80211_BPF_CTS) {
2240 if ((params->ibp_flags & IEEE80211_BPF_NOACK) || ismcast)
2244 KASSERT(rt != NULL, (
"no rate table, mode %u", sc->
sc_curmode));
2248 try0 = params->ibp_try0;
2253 if (m0->m_flags & M_EAPOL) {
2263 if (ieee80211_get_toa_params(m0, NULL)) {
2264 device_printf(sc->
sc_dev,
2265 "%s: setting TX positioning bit\n", __func__);
2272 if (params->ibp_flags & IEEE80211_BPF_SHORTPRE)
2275 ismrr = (params->ibp_try1 != 0);
2276 txantenna = params->ibp_pri >> 2;
2294 ieee80211_dump_pkt(ic, mtod(m0, caddr_t), m0->m_len,
2297 if (ieee80211_radiotap_active_vap(vap)) {
2299 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
2301 if (m0->m_flags & M_FRAG)
2305 ieee80211_get_node_txpower(ni));
2308 ieee80211_radiotap_tx(vap, m0);
2322 ieee80211_get_node_txpower(ni));
2329 !! (params->ibp_flags & IEEE80211_BPF_SHORTPRE);
2376 DPRINTF(sc, ATH_DEBUG_SW_TX,
"%s: dooverride=%d\n",
2377 __func__, do_override);
2421 const struct ieee80211_bpf_params *params)
2423 struct ieee80211com *ic = ni->ni_ic;
2426 struct ieee80211_frame *wh = mtod(m,
struct ieee80211_frame *);
2432 "%s: sc_inreset_cnt > 0; bailing\n", __func__);
2448 DPRINTF(sc, ATH_DEBUG_XMIT,
"%s: discard frame, r/i: %d/%d",
2460 if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
2483 ATH_KTR(sc, ATH_KTR_TX, 3,
"ath_raw_xmit: m=%p, params=%p, bf=%p\n",
2486 if (params == NULL) {
2529 ATH_KTR(sc, ATH_KTR_TX, 3,
"ath_raw_xmit: bad2: m=%p, params=%p, "
2551 ATH_KTR(sc, ATH_KTR_TX, 2,
"ath_raw_xmit: bad0: m=%p, params=%p",
2589 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) !=
2590 IEEE80211_FC0_TYPE_MGT)
2594 if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) !=
2595 IEEE80211_FC0_SUBTYPE_ACTION)
2608 struct ieee80211_node *ni,
2609 struct mbuf *m0,
int *tid)
2611 struct ieee80211_frame *wh = mtod(m0,
struct ieee80211_frame *);
2612 struct ieee80211_action_ba_addbarequest *ia;
2614 uint16_t baparamset;
2623 if (! ieee80211_parse_action(ni, m))
2628 frm = (u_int8_t *)&wh[1];
2629 ia = (
struct ieee80211_action_ba_addbarequest *) frm;
2632 if (ia->rq_header.ia_category != IEEE80211_ACTION_CAT_BA)
2634 if (ia->rq_header.ia_action != IEEE80211_ACTION_BA_ADDBA_REQUEST)
2638 baparamset = le16toh(ia->rq_baparamset);
2639 *tid = (int) _IEEE80211_MASKSHIFT(baparamset, IEEE80211_BAPS_TID);
2661 struct ieee80211_tx_ampdu *tap;
2671 DPRINTF(sc, ATH_DEBUG_SW_TX_BAW,
2672 "%s: dobaw=0, seqno=%d, window %d:%d\n",
2674 tap->txa_start, tap->txa_wnd);
2678 DPRINTF(sc, ATH_DEBUG_SW_TX_BAW,
2679 "%s: re-added? tid=%d, seqno %d; window %d:%d; "
2680 "baw head=%d tail=%d\n",
2682 tap->txa_start, tap->txa_wnd, tid->
baw_head,
2689 if (!
BAW_WITHIN(tap->txa_start, tap->txa_wnd,
2691 DPRINTF(sc, ATH_DEBUG_SW_TX_BAW,
2692 "%s: bf=%p: outside of BAW?? tid=%d, seqno %d; window %d:%d; "
2693 "baw head=%d tail=%d\n",
2695 tap->txa_start, tap->txa_wnd, tid->
baw_head,
2705 DPRINTF(sc, ATH_DEBUG_SW_TX_BAW,
2706 "%s: tid=%d, seqno %d; window %d:%d; index=%d cindex=%d "
2707 "baw head=%d tail=%d\n",
2709 tap->txa_start, tap->txa_wnd, index, cindex, tid->
baw_head,
2713 assert(tid->
tx_buf[cindex] == NULL);
2715 if (tid->
tx_buf[cindex] != NULL) {
2716 DPRINTF(sc, ATH_DEBUG_SW_TX_BAW,
2717 "%s: ba packet dup (index=%d, cindex=%d, "
2718 "head=%d, tail=%d)\n",
2720 DPRINTF(sc, ATH_DEBUG_SW_TX_BAW,
2721 "%s: BA bf: %p; seqno=%d ; new bf: %p; seqno=%d\n",
2729 tid->
tx_buf[cindex] = bf;
2752 struct ieee80211_tx_ampdu *tap;
2767 DPRINTF(sc, ATH_DEBUG_SW_TX_BAW,
2768 "%s: retransmitted buffer"
2769 " has mismatching seqno's, BA session may hang.\n",
2771 DPRINTF(sc, ATH_DEBUG_SW_TX_BAW,
2772 "%s: old seqno=%d, new_seqno=%d\n", __func__,
2776 if (tid->
tx_buf[cindex] != old_bf) {
2777 DPRINTF(sc, ATH_DEBUG_SW_TX_BAW,
2778 "%s: ath_buf pointer incorrect; "
2779 " has m BA session may hang.\n", __func__);
2780 DPRINTF(sc, ATH_DEBUG_SW_TX_BAW,
2781 "%s: old bf=%p, new bf=%p\n", __func__, old_bf, new_bf);
2784 tid->
tx_buf[cindex] = new_bf;
2799 struct ieee80211_tx_ampdu *tap;
2808 DPRINTF(sc, ATH_DEBUG_SW_TX_BAW,
2809 "%s: tid=%d, baw=%d:%d, seqno=%d, index=%d, cindex=%d, "
2810 "baw head=%d, tail=%d\n",
2811 __func__, tid->
tid, tap->txa_start, tap->txa_wnd, seqno, index,
2824 if (tid->
tx_buf[cindex] != bf) {
2825 DPRINTF(sc, ATH_DEBUG_SW_TX_BAW,
2826 "%s: comp bf=%p, seq=%d; slot bf=%p, seqno=%d\n",
2829 (tid->
tx_buf[cindex] != NULL) ?
2833 tid->
tx_buf[cindex] = NULL;
2837 INCR(tap->txa_start, IEEE80211_SEQ_RANGE);
2840 DPRINTF(sc, ATH_DEBUG_SW_TX_BAW,
2841 "%s: tid=%d: baw is now %d:%d, baw head=%d\n",
2842 __func__, tid->
tid, tap->txa_start, tap->txa_wnd, tid->
baw_head);
2849 struct ieee80211_frame *wh;
2854 wh = mtod(bf->
bf_m,
struct ieee80211_frame *);
2861 wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA;
2863 wh->i_fc[1] &= ~IEEE80211_FC1_MORE_DATA;
2865 DPRINTF(sc, ATH_DEBUG_NODE_PWRSAVE,
2866 "%s: %6D: leak count = %d, psq=%d, swq=%d, MORE=%d\n",
2873 !! (wh->i_fc[1] & IEEE80211_FC1_MORE_DATA));
2879 BUS_DMASYNC_PREWRITE);
2933 TAILQ_INSERT_HEAD(&txq->axq_tidq, tid, axq_qelem);
2935 TAILQ_INSERT_TAIL(&txq->axq_tidq, tid, axq_qelem);
2951 TAILQ_INSERT_TAIL(&txq->axq_tidq, tid, axq_qelem);
2967 if (tid->
sched == 0)
2971 TAILQ_REMOVE(&txq->axq_tidq, tid, axq_qelem);
2985 struct ath_buf *bf,
struct mbuf *m0)
2987 struct ieee80211_frame *wh;
2989 ieee80211_seq seqno;
2992 wh = mtod(m0,
struct ieee80211_frame *);
2993 tid = ieee80211_gettid(wh);
2995 DPRINTF(sc, ATH_DEBUG_SW_TX,
"%s: tid=%d, qos has seq=%d\n",
2996 __func__, tid, IEEE80211_QOS_HAS_SEQ(wh));
3001 if (! IEEE80211_QOS_HAS_SEQ(wh))
3015 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
3016 if (subtype == IEEE80211_FC0_SUBTYPE_QOS_NULL) {
3018 seqno = ni->ni_txseqs[IEEE80211_NONQOS_TID];
3019 INCR(ni->ni_txseqs[IEEE80211_NONQOS_TID], IEEE80211_SEQ_RANGE);
3020 }
else if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
3025 seqno = ni->ni_txseqs[IEEE80211_NONQOS_TID];
3026 INCR(ni->ni_txseqs[IEEE80211_NONQOS_TID], IEEE80211_SEQ_RANGE);
3029 seqno = ni->ni_txseqs[tid];
3030 INCR(ni->ni_txseqs[tid], IEEE80211_SEQ_RANGE);
3032 *(uint16_t *)&wh->i_seq[0] = htole16(seqno << IEEE80211_SEQ_SEQ_SHIFT);
3033 M_SEQNO_SET(m0, seqno);
3037 "%s: -> subtype=0x%x, tid=%d, seqno=%d\n",
3038 __func__, subtype, tid, seqno);
3052 struct ieee80211_tx_ampdu *tap;
3085 DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR,
3086 "%s: bfs_aggr=%d, bfs_nframes=%d\n", __func__,
3141 struct ieee80211_frame *wh;
3144 struct mbuf *m0 = bf->
bf_m;
3149 wh = mtod(m0,
struct ieee80211_frame *);
3154 DPRINTF(sc, ATH_DEBUG_SW_TX,
"%s: bf=%p, pri=%d, tid=%d, qos=%d\n",
3155 __func__, bf, pri, tid, IEEE80211_QOS_HAS_SEQ(wh));
3174 DPRINTF(sc, ATH_DEBUG_SW_TX,
"%s: paused\n", __func__);
3185 DPRINTF(sc, ATH_DEBUG_SW_TX,
"%s: pending\n", __func__);
3241 "%s: ampdu; swq'ing\n",
3263 DPRINTF(sc, ATH_DEBUG_SW_TX,
"%s: xmit_normal\n", __func__);
3280 DPRINTF(sc, ATH_DEBUG_SW_TX,
"%s: swq'ing\n", __func__);
3302 for (i = 0; i < IEEE80211_TID_SIZE; i++) {
3323 for (i = 0; i < IEEE80211_TID_SIZE; i++) {
3327 bzero(atid,
sizeof(*atid));
3329 TAILQ_INIT(&atid->tid_q);
3330 TAILQ_INIT(&atid->
filtq.tid_q);
3340 if (i == IEEE80211_NONQOS_TID)
3343 atid->
ac = TID_TO_WME_AC(i);
3361 DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL,
"%s: [%6D]: tid=%d, paused = %d\n",
3363 tid->an->an_node.ni_macaddr,
":",
3381 if (
tid->paused == 0) {
3382 device_printf(sc->
sc_dev,
3383 "%s: [%6D]: tid=%d, paused=0?\n",
3385 tid->an->an_node.ni_macaddr,
":",
3391 DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL,
3392 "%s: [%6D]: tid=%d, unpaused = %d\n",
3394 tid->an->an_node.ni_macaddr,
":",
3407 if (
tid->axq_depth == 0)
3411 if (
tid->isfiltered == 1) {
3412 DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL,
"%s: filtered?!\n",
3436 if (!
tid->isfiltered)
3437 DPRINTF(sc, ATH_DEBUG_SW_TX_FILT,
"%s: not filtered?!\n",
3440 DPRINTF(sc, ATH_DEBUG_SW_TX_FILT,
"%s: bf=%p\n", __func__, bf);
3461 if (!
tid->isfiltered) {
3462 DPRINTF(sc, ATH_DEBUG_SW_TX_FILT,
"%s: tid=%d; filter transition\n",
3463 __func__,
tid->tid);
3464 tid->isfiltered = 1;
3490 DPRINTF(sc, ATH_DEBUG_SW_TX_FILT,
"%s: tid=%d, hwq=0, transition back\n",
3491 __func__, tid->
tid);
3536 DPRINTF(sc, ATH_DEBUG_SW_TX_FILT,
3537 "%s: bf=%p, seqno=%d, exceeded retries\n",
3551 DPRINTF(sc, ATH_DEBUG_SW_TX_FILT,
3552 "%s: busy buffer clone: %p -> %p\n",
3559 DPRINTF(sc, ATH_DEBUG_SW_TX_FILT,
3560 "%s: busy buffer couldn't be cloned (%p)!\n",
3575 struct ath_buf *bf_first, ath_bufhead *bf_q)
3591 DPRINTF(sc, ATH_DEBUG_SW_TX_FILT,
3592 "%s: tid=%d, bf=%p, seqno=%d, exceeded retries\n",
3597 TAILQ_INSERT_TAIL(bf_q, bf, bf_list);
3603 DPRINTF(sc, ATH_DEBUG_SW_TX_FILT,
3604 "%s: tid=%d, busy buffer cloned: %p -> %p, seqno=%d\n",
3615 DPRINTF(sc, ATH_DEBUG_SW_TX_FILT,
3616 "%s: tid=%d, buffer couldn't be cloned! (%p) seqno=%d\n",
3618 TAILQ_INSERT_TAIL(bf_q, bf, bf_list);
3638 DPRINTF(sc, ATH_DEBUG_SW_TX_BAR,
3639 "%s: tid=%d, bar_wait=%d, bar_tx=%d, called\n",
3647 DPRINTF(sc, ATH_DEBUG_SW_TX_BAR,
3648 "%s: bar_tx is 1?!\n", __func__);
3672 DPRINTF(sc, ATH_DEBUG_SW_TX_BAR,
3673 "%s: %6D: TID=%d, called\n",
3680 DPRINTF(sc, ATH_DEBUG_SW_TX_BAR,
3681 "%s: %6D: TID=%d, bar_tx=%d, bar_wait=%d: ?\n",
3682 __func__, tid->
an->
an_node.ni_macaddr,
":",
3704 DPRINTF(sc, ATH_DEBUG_SW_TX_BAR,
3705 "%s: %6D: TID=%d, bar ready\n",
3729 struct ieee80211_tx_ampdu *tap;
3733 DPRINTF(sc, ATH_DEBUG_SW_TX_BAR,
3734 "%s: %6D: TID=%d, called\n",
3746 DPRINTF(sc, ATH_DEBUG_SW_TX_BAR,
3747 "%s: %6D: TID=%d, bar_tx=%d, bar_wait=%d: ?\n",
3748 __func__, tid->
an->
an_node.ni_macaddr,
":",
3755 DPRINTF(sc, ATH_DEBUG_SW_TX_BAR,
3756 "%s: %6D: TID=%d, hwq_depth=%d, waiting\n",
3780 DPRINTF(sc, ATH_DEBUG_SW_TX_BAR,
3781 "%s: %6D: TID=%d, new BAW left edge=%d\n",
3792 if (ieee80211_send_bar(&tid->
an->
an_node, tap, tap->txa_start) == 0) {
3800 DPRINTF(sc, ATH_DEBUG_SW_TX_BAR,
3801 "%s: %6D: TID=%d, failed to TX BAR, continue!\n",
3802 __func__, tid->
an->
an_node.ni_macaddr,
":",
3834 DPRINTF(sc, ATH_DEBUG_SW_TX_BAW
3835 "%s: wasn't added: seqno %d\n",
3844 TAILQ_INSERT_TAIL(bf_cq, bf, bf_list);
3851 struct ieee80211_node *ni = &an->
an_node;
3853 struct ieee80211_tx_ampdu *tap;
3858 DPRINTF(sc, ATH_DEBUG_SW_TX | ATH_DEBUG_RESET,
3859 "%s: %s: %6D: bf=%p: addbaw=%d, dobaw=%d, "
3860 "seqno=%d, retry=%d\n",
3870 DPRINTF(sc, ATH_DEBUG_SW_TX | ATH_DEBUG_RESET,
3871 "%s: %s: %6D: bf=%p: txq[%d] axq_depth=%d, axq_aggr_depth=%d\n",
3880 DPRINTF(sc, ATH_DEBUG_SW_TX | ATH_DEBUG_RESET,
3881 "%s: %s: %6D: bf=%p: tid txq_depth=%d hwq_depth=%d, bar_wait=%d, "
3892 DPRINTF(sc, ATH_DEBUG_SW_TX | ATH_DEBUG_RESET,
3893 "%s: %s: %6D: tid %d: "
3894 "sched=%d, paused=%d, "
3895 "incomp=%d, baw_head=%d, "
3896 "baw_tail=%d txa_start=%d, ni_txseqs=%d\n",
3904 tid->
baw_tail, tap == NULL ? -1 : tap->txa_start,
3905 ni->ni_txseqs[tid->
tid]);
3909 ieee80211_dump_pkt(ni->ni_ic,
3910 mtod(bf->
bf_m,
const uint8_t *),
3911 bf->
bf_m->m_len, 0, -1);
3931 struct ath_tid *tid, ath_bufhead *bf_cq)
3934 struct ieee80211_tx_ampdu *tap;
3935 struct ieee80211_node *ni = &an->
an_node;
4000 DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL,
4001 "%s: %6D: node %p: TID %d: sliding BAW left edge to %d\n",
4009 ni->ni_txseqs[tid->
tid] = tap->txa_start;
4097 ATH_KTR(sc, ATH_KTR_NODE, 1,
"ath_tx_node_flush: flush node; ni=%p",
4102 "%s: %6D: flush; is_powersave=%d, stack_psq=%d, tim=%d, "
4103 "swq_depth=%d, clrdmask=%d, leak_count=%d\n",
4114 for (tid = 0; tid < IEEE80211_TID_SIZE; tid++) {
4134 while ((bf = TAILQ_FIRST(&bf_cq)) != NULL) {
4135 TAILQ_REMOVE(&bf_cq, bf, bf_list);
4157 while (! TAILQ_EMPTY(&txq->axq_tidq)) {
4158 tid = TAILQ_FIRST(&txq->axq_tidq);
4165 while ((bf = TAILQ_FIRST(&bf_cq)) != NULL) {
4166 TAILQ_REMOVE(&bf_cq, bf, bf_list);
4190 struct ieee80211_node *ni = bf->
bf_node;
4199 DPRINTF(sc, ATH_DEBUG_SW_TX,
"%s: bf=%p: fail=%d, hwq_depth now %d\n",
4200 __func__, bf, fail, atid->
hwq_depth - 1);
4212 "%s: isfiltered=%d, ts_status=%d: huh?\n",
4220 DPRINTF(sc, ATH_DEBUG_SW_TX,
"%s: filtered?!\n", __func__);
4222 DPRINTF(sc, ATH_DEBUG_SW_TX,
"%s: hwq_depth < 0: %d\n",
4230 DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL,
4231 "%s: TID %d: cleaned up! resume!\n",
4277 struct ieee80211_node *ni = bf->
bf_node;
4282 DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL,
"%s: TID %d: incomp=%d\n",
4293 "%s: wasn't added: seqno %d\n",
4298 DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL,
4299 "%s: TID %d: cleaned up! resume!\n",
4316 int tid,
struct ath_buf *bf_head, ath_bufhead *bf_cq)
4332 while (bf != NULL) {
4357 TAILQ_INSERT_TAIL(bf_cq, bf, bf_list);
4388 DPRINTF(sc, ATH_DEBUG_SW_TX_BAW,
4389 "%s: TID %d: called; inprogress=%d\n", __func__, tid,
4415 bf_next = TAILQ_NEXT(bf, bf_list);
4443 DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL,
4444 "%s: TID %d: cleanup needed: %d packets\n",
4445 __func__, tid, atid->
incomp);
4466 DPRINTF(sc, ATH_DEBUG_XMIT,
"%s: ATH_BUF_BUSY; cloning\n",
4473 "%s: failed to clone a busy buffer\n",
4482 "%s: failed to setup dma for clone\n",
4519 struct ieee80211_node *ni = bf->
bf_node;
4523 struct ieee80211_tx_ampdu *tap;
4549 DPRINTF(sc, ATH_DEBUG_SW_TX_RETRIES,
4550 "%s: exceeded retries; seqno %d\n",
4558 DPRINTF(sc, ATH_DEBUG_SW_TX_BAW,
4559 "%s: wasn't added: seqno %d\n",
4610 struct ieee80211_node *ni = bf->
bf_node;
4644 DPRINTF(sc, ATH_DEBUG_SW_TX_RETRIES,
4645 "%s: max retries: seqno %d\n",
4649 DPRINTF(sc, ATH_DEBUG_SW_TX_BAW,
4650 "%s: wasn't added: seqno %d\n",
4665 TAILQ_INSERT_TAIL(bf_q, bf, bf_list);
4676 struct ieee80211_node *ni = bf_first->
bf_node;
4681 struct ieee80211_tx_ampdu *tap;
4709 TAILQ_INSERT_TAIL(&bf_cq, bf, bf_list);
4715 while ((bf = TAILQ_LAST(&bf_q, ath_bufhead_s)) != NULL) {
4716 TAILQ_REMOVE(&bf_q, bf, bf_list);
4746 while ((bf = TAILQ_FIRST(&bf_cq)) != NULL) {
4747 TAILQ_REMOVE(&bf_cq, bf, bf_list);
4762 struct ieee80211_node *ni = bf_first->
bf_node;
4780 "%s: wasn't added: seqno %d\n",
4787 DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL,
4788 "%s: TID %d: cleaned up! resume!\n",
4826 struct ieee80211_node *ni = bf_first->
bf_node;
4831 struct ieee80211_tx_ampdu *tap;
4840 int nframes = 0, nbad = 0, nf;
4842 int agglen, rc_agglen;
4847 DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR,
"%s: called; hwq_depth=%d\n",
4866 DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR,
"%s: hwq_depth < 0: %d\n",
4884 DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR,
4885 "%s: isfiltered=1, normal_comp?\n",
4902 DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR,
4903 "%s: isfiltered=1, fail=%d\n", __func__, fail);
4907 TAILQ_FOREACH_SAFE(bf, &bf_cq, bf_list, bf_next) {
4913 DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR,
4914 "%s: wasn't added: seqno %d\n",
4931 goto finish_send_bar;
4977 DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR,
4978 "%s: txa_start=%d, tx_ok=%d, status=%.8x, flags=%.8x, "
4979 "isaggr=%d, seq_st=%d, hasba=%d, ba=%.8x, %.8x\n",
4981 isaggr, seq_st, hasba, ba[0], ba[1]);
4995 DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR,
"%s: tid %d != hw tid %d\n",
4996 __func__, tid, ts.
ts_tid);
5002 if (isaggr && tx_ok && (! hasba)) {
5003 device_printf(sc->
sc_dev,
5004 "%s: AR5416 bug: hasba=%d; txok=%d, isaggr=%d, "
5006 __func__, hasba, tx_ok, isaggr, seq_st);
5013 ath_printtxbuf(sc, bf_first,
5049 DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR,
5050 "%s: checking bf=%p seqno=%d; ack=%d\n",
5059 DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR,
5060 "%s: wasn't added: seqno %d\n",
5063 TAILQ_INSERT_TAIL(&bf_cq, bf, bf_list);
5069 TAILQ_INSERT_TAIL(&bf_cq, bf, bf_list);
5084 txseq = tap->txa_start;
5088 DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR,
5089 "%s: num frames seen=%d; bf nframes=%d\n",
5090 __func__, nframes, nf);
5111 DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR,
5112 "%s: txa_start now %d\n", __func__, tap->txa_start);
5117 while ((bf = TAILQ_LAST(&bf_q, ath_bufhead_s)) != NULL) {
5118 TAILQ_REMOVE(&bf_q, bf, bf_list);
5151 while ((bf = TAILQ_FIRST(&bf_cq)) != NULL) {
5152 TAILQ_REMOVE(&bf_cq, bf, bf_list);
5167 struct ieee80211_node *ni = bf->
bf_node;
5200 if (tid == IEEE80211_NONQOS_TID)
5201 DPRINTF(sc, ATH_DEBUG_SW_TX,
"%s: TID=16!\n", __func__);
5204 "%s: bf=%p: tid=%d, hwq_depth=%d, seqno=%d\n",
5210 DPRINTF(sc, ATH_DEBUG_SW_TX,
"%s: hwq_depth < 0: %d\n",
5230 "%s: isfiltered=1, normal_comp?\n",
5233 DPRINTF(sc, ATH_DEBUG_SW_TX,
"%s: cleanup_unaggr\n",
5257 "%s: isfiltered=1, fail=%d\n",
5272 "%s: wasn't added: seqno %d\n",
5282 if (freeframe && drops)
5310 DPRINTF(sc, ATH_DEBUG_SW_TX,
"%s: retry_unaggr\n",
5317 DPRINTF(sc, ATH_DEBUG_SW_TX,
"%s: TID=%d, seqno %d\n",
5324 "%s: wasn't added: seqno %d\n",
5375 struct ieee80211_tx_ampdu *tap;
5387 TAILQ_FOREACH(bf, &tid->tid_q, bf_list) {
5394 if (tap != NULL && (!
BAW_WITHIN(tap->txa_start, tap->txa_wnd,
5432 struct ieee80211_tx_ampdu *tap;
5437 DPRINTF(sc, ATH_DEBUG_SW_TX,
"%s: tid=%d\n", __func__, tid->
tid);
5447 if (tid->
tid == IEEE80211_NONQOS_TID)
5449 "%s: called for TID=NONQOS_TID?\n", __func__);
5475 DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR,
5476 "%s: non-baw packet\n",
5482 "%s: aggr=%d, nframes=%d\n",
5537 DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR,
5538 "%s: ath_tx_form_aggr() status=%d\n", __func__, status);
5543 if (TAILQ_EMPTY(&bf_q))
5550 bf = TAILQ_FIRST(&bf_q);
5561 DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR,
5562 "%s: single-frame aggregate\n", __func__);
5576 DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR,
5577 "%s: multi-frame aggregate: %d frames, "
5613 DPRINTF(sc, ATH_DEBUG_SW_TX,
"%s: TID=16?\n", __func__);
5664 DPRINTF(sc, ATH_DEBUG_SW_TX,
"%s: node %p: TID %d: called\n",
5665 __func__, an, tid->
tid);
5671 DPRINTF(sc, ATH_DEBUG_SW_TX,
"%s: tid=%d, ampdu pending?\n",
5672 __func__, tid->
tid);
5674 DPRINTF(sc, ATH_DEBUG_SW_TX,
"%s: tid=%d, ampdu running?\n",
5675 __func__, tid->
tid);
5697 DPRINTF(sc, ATH_DEBUG_SW_TX,
"%s: bfs_tid %d !="
5795 last = TAILQ_LAST(&txq->axq_tidq, axq_t_s);
5797 TAILQ_FOREACH_SAFE(
tid, &txq->axq_tidq, axq_qelem, next) {
5802 DPRINTF(sc, ATH_DEBUG_SW_TX,
"%s: tid=%d, paused=%d\n",
5803 __func__,
tid->tid,
tid->paused);
5818 if (
tid->axq_depth != 0)
5856struct ieee80211_tx_ampdu *
5859 struct ieee80211_node *ni = &an->
an_node;
5860 struct ieee80211_tx_ampdu *tap;
5862 if (tid == IEEE80211_NONQOS_TID)
5865 tap = &ni->ni_tx_ampdu[tid];
5875 struct ieee80211_tx_ampdu *tap;
5877 if (tid == IEEE80211_NONQOS_TID)
5884 return !! (tap->txa_flags & IEEE80211_AGGR_RUNNING);
5893 struct ieee80211_tx_ampdu *tap;
5895 if (tid == IEEE80211_NONQOS_TID)
5902 return !! (tap->txa_flags & IEEE80211_AGGR_XCHGPEND);
5919 int dialogtoken,
int baparamset,
int batimeout)
5921 struct ath_softc *sc = ni->ni_ic->ic_softc;
5922 int tid = tap->txa_tid;
5961 DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL,
5962 "%s: %6D: called; dialogtoken=%d, baparamset=%d, batimeout=%d\n",
5966 dialogtoken, baparamset, batimeout);
5967 DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL,
5968 "%s: txa_start=%d, ni_txseqs=%d\n",
5969 __func__, tap->txa_start, ni->ni_txseqs[
tid]);
5997 int status,
int code,
int batimeout)
5999 struct ath_softc *sc = ni->ni_ic->ic_softc;
6000 int tid = tap->txa_tid;
6005 DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL,
6006 "%s: %6D: called; status=%d, code=%d, batimeout=%d\n", __func__,
6009 status, code, batimeout);
6011 DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL,
6012 "%s: txa_start=%d, ni_txseqs=%d\n",
6013 __func__, tap->txa_start, ni->ni_txseqs[
tid]);
6030 tap->txa_start = ni->ni_txseqs[
tid];
6045 struct ath_softc *sc = ni->ni_ic->ic_softc;
6046 int tid = tap->txa_tid;
6052 DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL,
"%s: %6D: called\n",
6107 while ((bf = TAILQ_FIRST(&bf_cq)) != NULL) {
6108 TAILQ_REMOVE(&bf_cq, bf, bf_list);
6133 for (i = 0; i < IEEE80211_TID_SIZE; i++) {
6138 "%s: %6D: TID %d: cleaning up TID\n",
6160 while ((bf = TAILQ_FIRST(&bf_cq)) != NULL) {
6161 TAILQ_REMOVE(&bf_cq, bf, bf_list);
6180 struct ath_softc *sc = ni->ni_ic->ic_softc;
6181 int tid = tap->txa_tid;
6184 int attempts = tap->txa_attempts;
6187 DPRINTF(sc, ATH_DEBUG_SW_TX_BAR,
6188 "%s: %6D: called; txa_tid=%d, atid->tid=%d, status=%d, attempts=%d, txa_start=%d, txa_seqpending=%d\n",
6197 tap->txa_seqpending);
6211 old_txa_start = tap->txa_start;
6213 if (tap->txa_start != old_txa_start) {
6214 device_printf(sc->
sc_dev,
"%s: tid=%d; txa_start=%d, old=%d, adjusting\n",
6220 tap->txa_start = old_txa_start;
6232 if (status == 0 || attempts == 50) {
6235 DPRINTF(sc, ATH_DEBUG_SW_TX_BAR,
6236 "%s: huh? bar_tx=%d, bar_wait=%d\n",
6251 struct ieee80211_tx_ampdu *tap)
6253 struct ath_softc *sc = ni->ni_ic->ic_softc;
6254 int tid = tap->txa_tid;
6258 DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL,
6259 "%s: %6D: TID=%d, called; resuming\n",
6322 "%s: %6D: node was already asleep!\n",
6323 __func__, an->
an_node.ni_macaddr,
":");
6328 for (tid = 0; tid < IEEE80211_TID_SIZE; tid++) {
6360 "%s: an=%p: node was already awake\n",
6372 for (tid = 0; tid < IEEE80211_TID_SIZE; tid++) {
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)
@ HAL_PKT_TYPE_PROBE_RESP
#define HAL_TXDESC_INTREQ
#define HAL_TXKEYIX_INVALID
#define HAL_TXDESC_CTSENA
#define HAL_TXDESC_CLRDMASK
#define HAL_TXDESC_RTSENA
#define IEEE80211_CRC_LEN
void ath_rate_findrate(struct ath_softc *sc, struct ath_node *an, int shortPreamble, size_t frameLen, int tid, int is_aggr, u_int8_t *rix, int *try0, u_int8_t *txrate, int *maxdur, int *maxpktlen)
void ath_rate_getxtxrates(struct ath_softc *sc, struct ath_node *an, uint8_t rix0, int is_aggr, struct ath_rc_series *rc)
int ath_tx_findrix(const struct ath_softc *sc, uint8_t rate)
void ath_tx_update_ratectrl(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_rc_series *rc, struct ath_tx_status *ts, int frmlen, int rc_framelen, int nframes, int nbad)
void ath_legacy_attach_comp_func(struct ath_softc *sc)
struct ath_buf * ath_buf_clone(struct ath_softc *sc, struct ath_buf *bf)
struct ath_buf * ath_getbuf(struct ath_softc *sc, ath_buf_type_t btype)
void ath_tx_default_comp(struct ath_softc *sc, struct ath_buf *bf, int fail)
void ath_tx_update_tim(struct ath_softc *sc, struct ieee80211_node *ni, int enable)
struct ath_buf * _ath_getbuf_locked(struct ath_softc *sc, ath_buf_type_t btype)
void ath_freebuf(struct ath_softc *sc, struct ath_buf *bf)
void ath_legacy_tx_drain(struct ath_softc *sc, ATH_RESET_TYPE reset_type)
void ath_returnbuf_head(struct ath_softc *sc, struct ath_buf *bf)
#define ATH_ALQ_EDMA_TXDESC
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_KTR(_sc, _km, _kf,...)
#define IFF_DUMPPKTS(sc, m)
#define DPRINTF(sc, m, fmt,...)
#define ath_power_restore_power_state(sc)
void ath_tx_dump(struct ath_softc *sc, struct ath_txq *txq)
#define ath_power_set_power_state(sc, ps)
static void ath_tx_swq_kick(struct ath_softc *sc)
static int ieee80211_is_action(struct ieee80211_frame *wh)
static void ath_tx_tid_drain(struct ath_softc *sc, struct ath_node *an, struct ath_tid *tid, ath_bufhead *bf_cq)
static void ath_tx_setds_11n(struct ath_softc *sc, struct ath_buf *bf_first)
static void ath_tx_comp_cleanup_unaggr(struct ath_softc *sc, struct ath_buf *bf)
void ath_tx_txq_drain(struct ath_softc *sc, struct ath_txq *txq)
int ath_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params)
static int ath_tx_gettid(struct ath_softc *sc, const struct mbuf *m0)
static void ath_tx_set_retry(struct ath_softc *sc, struct ath_buf *bf)
static void ath_tx_tid_cleanup_frame(struct ath_softc *sc, struct ath_node *an, int tid, struct ath_buf *bf_head, ath_bufhead *bf_cq)
static void ath_tx_tid_bar_unsuspend(struct ath_softc *sc, struct ath_tid *tid)
static void ath_tx_tid_resume(struct ath_softc *sc, struct ath_tid *tid)
static int ath_tx_should_swq_frame(struct ath_softc *sc, struct ath_node *an, struct mbuf *m0, int *queue_to_head)
static void ath_tx_set_rtscts(struct ath_softc *sc, struct ath_buf *bf)
static void ath_tx_aggr_comp_aggr(struct ath_softc *sc, struct ath_buf *bf_first, int fail)
static int ath_tx_retry_subframe(struct ath_softc *sc, struct ath_buf *bf, ath_bufhead *bf_q)
int ath_addba_request(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, int dialogtoken, int baparamset, int batimeout)
void ath_txq_sched(struct ath_softc *sc, struct ath_txq *txq)
void ath_tx_node_sleep(struct ath_softc *sc, struct ath_node *an)
static int ath_tx_calc_ctsduration(struct ath_hal *ah, int rix, int cix, int shortPreamble, int pktlen, const HAL_RATE_TABLE *rt, int flags)
static void ath_tx_setds(struct ath_softc *sc, struct ath_buf *bf)
void ath_tx_aggr_comp(struct ath_softc *sc, struct ath_buf *bf, int fail)
static void ath_tx_update_clrdmask(struct ath_softc *sc, struct ath_tid *tid, struct ath_buf *bf)
static void ath_tx_tid_bar_tx(struct ath_softc *sc, struct ath_tid *tid)
void ath_bar_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, int status)
static int ath_legacy_dma_txsetup(struct ath_softc *sc)
static void ath_tx_tid_filt_comp_buf(struct ath_softc *sc, struct ath_tid *tid, struct ath_buf *bf)
static void ath_tx_calc_duration(struct ath_softc *sc, struct ath_buf *bf)
struct ieee80211_tx_ampdu * ath_tx_get_tx_tid(struct ath_node *an, int tid)
static void ath_tx_aggr_comp_unaggr(struct ath_softc *sc, struct ath_buf *bf, int fail)
static int ath_tx_tid_bar_tx_ready(struct ath_softc *sc, struct ath_tid *tid)
void ath_addba_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap)
static void ath_tx_tid_bar_suspend(struct ath_softc *sc, struct ath_tid *tid)
static void ath_tx_tid_filt_comp_aggr(struct ath_softc *sc, struct ath_tid *tid, struct ath_buf *bf_first, ath_bufhead *bf_q)
void ath_tx_tid_hw_queue_norm(struct ath_softc *sc, struct ath_node *an, struct ath_tid *tid)
static void ath_tx_tid_drain_pkt(struct ath_softc *sc, struct ath_node *an, struct ath_tid *tid, ath_bufhead *bf_cq, struct ath_buf *bf)
static int ath_tx_tag_crypto(struct ath_softc *sc, struct ieee80211_node *ni, struct mbuf *m0, int iswep, int isfrag, int *hdrlen, int *pktlen, int *keyix)
static int ath_tx_ampdu_running(struct ath_softc *sc, struct ath_node *an, int tid)
void ath_tx_node_reassoc(struct ath_softc *sc, struct ath_node *an)
static void ath_tx_tid_pause(struct ath_softc *sc, struct ath_tid *tid)
static void ath_tx_xmit_normal(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf)
static int ath_tx_action_frame_override_queue(struct ath_softc *sc, struct ieee80211_node *ni, struct mbuf *m0, int *tid)
static void ath_legacy_xmit_handoff(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf)
void ath_tx_addto_baw(struct ath_softc *sc, struct ath_node *an, struct ath_tid *tid, struct ath_buf *bf)
int ath_tx_node_is_asleep(struct ath_softc *sc, struct ath_node *an)
static void ath_tx_handoff_mcast(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf)
static int ath_tx_is_11n(struct ath_softc *sc)
static void ath_tx_do_ratelookup(struct ath_softc *sc, struct ath_buf *bf, int tid, int pktlen, int is_aggr)
void ath_addba_response_timeout(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap)
void ath_tx_normal_comp(struct ath_softc *sc, struct ath_buf *bf, int fail)
static struct ath_buf * ath_tx_retry_clone(struct ath_softc *sc, struct ath_node *an, struct ath_tid *tid, struct ath_buf *bf)
int ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf, struct mbuf *m0)
static void ath_tx_comp_cleanup_aggr(struct ath_softc *sc, struct ath_buf *bf_first)
static void ath_tx_update_baw(struct ath_softc *sc, struct ath_node *an, struct ath_tid *tid, const struct ath_buf *bf)
static void ath_legacy_tx_dma_restart(struct ath_softc *sc, struct ath_txq *txq)
static int ath_legacy_dma_txteardown(struct ath_softc *sc)
static void ath_tx_calc_protection(struct ath_softc *sc, struct ath_buf *bf)
static int ath_tx_ampdu_pending(struct ath_softc *sc, struct ath_node *an, int tid)
static int ath_tx_tid_filt_comp_single(struct ath_softc *sc, struct ath_tid *tid, struct ath_buf *bf)
static int ath_tx_dmasetup(struct ath_softc *sc, struct ath_buf *bf, struct mbuf *m0)
static void ath_tx_tid_filt_comp_complete(struct ath_softc *sc, struct ath_tid *tid)
static void ath_tx_tid_unsched(struct ath_softc *sc, struct ath_tid *tid)
void ath_xmit_setup_legacy(struct ath_softc *sc)
static void ath_tx_comp_aggr_error(struct ath_softc *sc, struct ath_buf *bf_first, struct ath_tid *tid)
static ieee80211_seq ath_tx_tid_seqno_assign(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf, struct mbuf *m0)
static void ath_tx_aggr_retry_unaggr(struct ath_softc *sc, struct ath_buf *bf)
static void ath_tx_chaindesclist(struct ath_softc *sc, struct ath_desc *ds0, struct ath_buf *bf, bool is_aggr, int is_first_subframe, int is_last_subframe)
void ath_tx_node_wakeup(struct ath_softc *sc, struct ath_node *an)
static void ath_tx_tid_drain_print(struct ath_softc *sc, struct ath_node *an, const char *pfx, struct ath_tid *tid, struct ath_buf *bf)
static void ath_tx_leak_count_update(struct ath_softc *sc, struct ath_tid *tid, struct ath_buf *bf)
static void ath_tx_tid_filt_addbuf(struct ath_softc *sc, struct ath_tid *tid, struct ath_buf *bf)
static void ath_tx_tid_cleanup(struct ath_softc *sc, struct ath_node *an, int tid, ath_bufhead *bf_cq)
static void ath_tx_handoff_hw(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf)
static int ath_tx_tid_can_tx_or_sched(struct ath_softc *sc, struct ath_tid *tid)
#define ATH_NONQOS_TID_AC
void ath_tx_swq(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_txq *txq, int queue_to_head, struct ath_buf *bf)
static void ath_tx_switch_baw_buf(struct ath_softc *sc, struct ath_node *an, struct ath_tid *tid, struct ath_buf *old_bf, struct ath_buf *new_bf)
void ath_tx_tid_init(struct ath_softc *sc, struct ath_node *an)
static uint8_t ath_tx_get_rtscts_rate(struct ath_hal *ah, const HAL_RATE_TABLE *rt, int cix, int shortPreamble)
static void ath_tx_set_ratectrl(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf)
void ath_txfrag_cleanup(struct ath_softc *sc, ath_bufhead *frags, struct ieee80211_node *ni)
static void ath_tx_set_clrdmask(struct ath_softc *sc, struct ath_node *an)
static int ath_tx_normal_setup(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf, struct mbuf *m0, struct ath_txq *txq)
static void ath_tx_xmit_aggr(struct ath_softc *sc, struct ath_node *an, struct ath_txq *txq, struct ath_buf *bf)
void ath_tx_node_flush(struct ath_softc *sc, struct ath_node *an)
void ath_tx_tid_sched(struct ath_softc *sc, struct ath_tid *tid)
static int ath_tx_getac(struct ath_softc *sc, const struct mbuf *m0)
int ath_txfrag_setup(struct ath_softc *sc, ath_bufhead *frags, struct mbuf *m0, struct ieee80211_node *ni)
void ath_tx_tid_hw_queue_aggr(struct ath_softc *sc, struct ath_node *an, struct ath_tid *tid)
static void ath_tx_tid_reset(struct ath_softc *sc, struct ath_tid *tid)
static int ath_tx_tid_swq_depth_bytes(struct ath_softc *sc, struct ath_node *an, struct ath_tid *tid)
int ath_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, int status, int code, int batimeout)
static int ath_tx_raw_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf, struct mbuf *m0, const struct ieee80211_bpf_params *params)
#define ath_tx_handoff(_sc, _txq, _bf)
#define ATH_BA_ISSET(_bm, _n)
#define BAW_WITHIN(_start, _bawsz, _seqno)
#define ATH_BA_INDEX(_st, _seq)
void ath_buf_set_rate(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf)
ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, struct ath_node *an, struct ath_tid *tid, ath_bufhead *bf_q)
void ath_tx_rate_fill_rcflags(struct ath_softc *sc, struct ath_buf *bf)
#define ath_hal_set11n_aggr_last(_ah, _ds)
#define ATH_BUF_TOA_PROBE
#define ATH_TID_INSERT_HEAD(_tq, _elm, _field)
#define ath_hal_set11nburstduration(_ah, _ds, _dur)
#define ATH_TID_FILT_REMOVE(_tq, _elm, _field)
#define ath_hal_puttxbuf(_ah, _q, _bufaddr)
#define ATH_TID_FILT_INSERT_TAIL(_tq, _elm, _field)
#define ath_hal_clr11n_aggr(_ah, _ds)
#define ATH_TXBUF_LOCK(_sc)
#define ATH_TID_INSERT_TAIL(_tq, _elm, _field)
#define ATH_TXQ_LAST(_tq, _field)
#define ath_hal_set11n_aggr_first(_ah, _ds, _len, _num)
#define ATH_NODE_LOCK(_an)
#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_NODE_UNLOCK(_an)
#define ATH_PCU_UNLOCK(_sc)
#define ATH_TX_LOCK_ASSERT(_sc)
#define ATH_TID_FIRST(_tq)
#define ATH_TID_REMOVE(_tq, _elm, _field)
#define ATH_TXQ_PUTRUNNING
#define ath_hal_setupxtxdesc(_ah, _ds, _txr1, _txtr1, _txr2, _txtr2, _txr3, _txtr3)
#define ATH_TXBUF_LOCK_ASSERT(_sc)
#define ath_hal_setuplasttxdesc(_ah, _ds, _ds0)
#define ATH_TXQ_LOCK(_tq)
#define ATH_TID_FILT_LAST(_tq, _field)
#define ATH_TXQ_UNLOCK(_tq)
#define ath_hal_set11n_aggr_middle(_ah, _ds, _num)
#define ATH_TX_UNLOCK(_sc)
#define ATH_TID_FILT_FIRST(_tq)
#define ATH_TX_UNLOCK_ASSERT(_sc)
#define ath_hal_settxdesclink(_ah, _ds, _link)
#define ath_hal_filltxdesc(_ah, _ds, _b, _l, _did, _qid, _first, _last, _ds0)
#define ATH_PCU_LOCK(_sc)
#define ath_hal_gettxdesclinkptr(_ah, _ds, _linkptr)
#define ATH_TXQ_INSERT_TAIL(_tq, _elm, _field)
#define ATH_TXBUF_UNLOCK(_sc)
#define ath_hal_txstart(_ah, _q)
struct HAL_RATE_TABLE::@3 info[64]
struct ath_desc_status bf_status
void(* bf_comp)(struct ath_softc *sc, struct ath_buf *bf, int fail)
struct ath_desc * bf_lastds
struct ath_desc * bf_desc
struct ath_rc_series bfs_rc[ATH_RC_NUM]
struct ath_buf::@32 bf_state
bus_dma_segment_t bf_segs[ATH_MAX_SCATTER]
struct ieee80211_node * bf_node
u_int32_t bfs_doratelookup
struct ath_tid an_tid[IEEE80211_TID_SIZE]
struct ieee80211_node an_node
void(* sc_addba_stop)(struct ieee80211_node *, struct ieee80211_tx_ampdu *)
struct ath_txq * sc_ac2q[5]
const HAL_RATE_TABLE * sc_currates
enum ieee80211_phymode sc_curmode
int(* sc_addba_request)(struct ieee80211_node *, struct ieee80211_tx_ampdu *, int, int, int)
int sc_txq_node_psq_maxdepth
int sc_txq_mcastq_maxdepth
struct ath_stats sc_stats
struct ath_tx_radiotap_header sc_tx_th
struct ath_tx_aggr_stats sc_aggr_stats
int(* sc_addba_response)(struct ieee80211_node *, struct ieee80211_tx_ampdu *, int, int, int)
void(* sc_bar_response)(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, int status)
struct ath_softc::@34 sc_hwmap[32]
struct ath_descdma sc_txdma
struct ath_tx_methods sc_tx
void(* sc_addba_response_timeout)(struct ieee80211_node *, struct ieee80211_tx_ampdu *)
struct ieee80211com sc_ic
u_int32_t ast_tx_swretries
u_int32_t ast_tx_node_psq_overflow
u_int32_t ast_tx_swfiltered
u_int32_t ast_tx_shortpre
u_int32_t ast_tx_mcastq_overflow
u_int32_t ast_tx_aggr_failall
u_int32_t ast_tx_aggr_fail
u_int32_t ast_tx_swretrymax
u_int32_t ast_tx_raw_fail
u_int32_t ast_tx_htprotect
struct ath_tid::@31 filtq
struct ath_buf * tx_buf[ATH_TID_MAX_BUFS]
u_int32_t aggr_baw_closed_single_pkt
u_int32_t aggr_single_pkt
u_int32_t aggr_sched_nopkt
u_int32_t aggr_rts_aggr_limited
u_int32_t aggr_nonbaw_pkt
u_int32_t aggr_low_hwq_single_pkt
void(* xmit_drain)(struct ath_softc *sc, ATH_RESET_TYPE reset_type)
void(* xmit_attach_comp_func)(struct ath_softc *sc)
int(* xmit_setup)(struct ath_softc *sc)
int(* xmit_teardown)(struct ath_softc *sc)
void(* xmit_handoff)(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf)
void(* xmit_dma_restart)(struct ath_softc *sc, struct ath_txq *txq)