Deleted Added
full compact
if_ath_tx.c (232794) if_ath_tx.c (233227)
1/*-
2 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 14 unchanged lines hidden (view full) ---

23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 * THE POSSIBILITY OF SUCH DAMAGES.
28 */
29
30#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 14 unchanged lines hidden (view full) ---

23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 * THE POSSIBILITY OF SUCH DAMAGES.
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath_tx.c 232794 2012-03-10 19:58:23Z adrian $");
31__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath_tx.c 233227 2012-03-20 04:50:25Z adrian $");
32
33/*
34 * Driver for the Atheros Wireless LAN controller.
35 *
36 * This software is derived from work of Atsushi Onoe; his contribution
37 * is greatly appreciated.
38 */
39

--- 64 unchanged lines hidden (view full) ---

104 * How many retries to perform in software
105 */
106#define SWMAX_RETRIES 10
107
108static int ath_tx_ampdu_pending(struct ath_softc *sc, struct ath_node *an,
109 int tid);
110static int ath_tx_ampdu_running(struct ath_softc *sc, struct ath_node *an,
111 int tid);
32
33/*
34 * Driver for the Atheros Wireless LAN controller.
35 *
36 * This software is derived from work of Atsushi Onoe; his contribution
37 * is greatly appreciated.
38 */
39

--- 64 unchanged lines hidden (view full) ---

104 * How many retries to perform in software
105 */
106#define SWMAX_RETRIES 10
107
108static int ath_tx_ampdu_pending(struct ath_softc *sc, struct ath_node *an,
109 int tid);
110static int ath_tx_ampdu_running(struct ath_softc *sc, struct ath_node *an,
111 int tid);
112static ieee80211_seq ath_tx_tid_seqno_assign(struct ath_softc *sc,
113 struct ieee80211_node *ni, struct ath_buf *bf, struct mbuf *m0);
114static int ath_tx_action_frame_override_queue(struct ath_softc *sc,
115 struct ieee80211_node *ni, struct mbuf *m0, int *tid);
112static int ath_tx_action_frame_override_queue(struct ath_softc *sc,
113 struct ieee80211_node *ni, struct mbuf *m0, int *tid);
114static int ath_tx_seqno_required(struct ath_softc *sc,
115 struct ieee80211_node *ni, struct ath_buf *bf, struct mbuf *m0);
116
117/*
118 * Whether to use the 11n rate scenario functions or not
119 */
120static inline int
121ath_tx_is_11n(struct ath_softc *sc)
122{
123 return (sc->sc_ah->ah_magic == 0x20065416);

--- 1247 unchanged lines hidden (view full) ---

1371 struct ath_vap *avp = ATH_VAP(vap);
1372 int r = 0;
1373 u_int pri;
1374 int tid;
1375 struct ath_txq *txq;
1376 int ismcast;
1377 const struct ieee80211_frame *wh;
1378 int is_ampdu, is_ampdu_tx, is_ampdu_pending;
116
117/*
118 * Whether to use the 11n rate scenario functions or not
119 */
120static inline int
121ath_tx_is_11n(struct ath_softc *sc)
122{
123 return (sc->sc_ah->ah_magic == 0x20065416);

--- 1247 unchanged lines hidden (view full) ---

1371 struct ath_vap *avp = ATH_VAP(vap);
1372 int r = 0;
1373 u_int pri;
1374 int tid;
1375 struct ath_txq *txq;
1376 int ismcast;
1377 const struct ieee80211_frame *wh;
1378 int is_ampdu, is_ampdu_tx, is_ampdu_pending;
1379 ieee80211_seq seqno;
1379 //ieee80211_seq seqno;
1380 uint8_t type, subtype;
1381
1382 /*
1383 * Determine the target hardware queue.
1384 *
1385 * For multicast frames, the txq gets overridden to be the
1386 * software TXQ and it's done via direct-dispatch.
1387 *

--- 35 unchanged lines hidden (view full) ---

1423 }
1424 }
1425
1426 /* A-MPDU TX */
1427 is_ampdu_tx = ath_tx_ampdu_running(sc, ATH_NODE(ni), tid);
1428 is_ampdu_pending = ath_tx_ampdu_pending(sc, ATH_NODE(ni), tid);
1429 is_ampdu = is_ampdu_tx | is_ampdu_pending;
1430
1380 uint8_t type, subtype;
1381
1382 /*
1383 * Determine the target hardware queue.
1384 *
1385 * For multicast frames, the txq gets overridden to be the
1386 * software TXQ and it's done via direct-dispatch.
1387 *

--- 35 unchanged lines hidden (view full) ---

1423 }
1424 }
1425
1426 /* A-MPDU TX */
1427 is_ampdu_tx = ath_tx_ampdu_running(sc, ATH_NODE(ni), tid);
1428 is_ampdu_pending = ath_tx_ampdu_pending(sc, ATH_NODE(ni), tid);
1429 is_ampdu = is_ampdu_tx | is_ampdu_pending;
1430
1431 DPRINTF(sc, ATH_DEBUG_SW_TX, "%s: tid=%d, ac=%d, is_ampdu=%d\n",
1432 __func__, tid, pri, is_ampdu);
1431 DPRINTF(sc, ATH_DEBUG_SW_TX,
1432 "%s: bf=%p, tid=%d, ac=%d, is_ampdu=%d\n",
1433 __func__, bf, tid, pri, is_ampdu);
1433
1434 /* Multicast frames go onto the software multicast queue */
1435 if (ismcast)
1436 txq = &avp->av_mcastq;
1437
1438 /*
1439 * XXX This likely means that if there's a station in power
1440 * save mode, we won't be doing any kind of aggregation towards
1441 * anyone. This is likely a very suboptimal way of dealing
1442 * with things.
1443 */
1444 if ((! is_ampdu) && (vap->iv_ps_sta || avp->av_mcastq.axq_depth))
1445 txq = &avp->av_mcastq;
1446
1447 /* Do the generic frame setup */
1448 /* XXX should just bzero the bf_state? */
1449 bf->bf_state.bfs_dobaw = 0;
1434
1435 /* Multicast frames go onto the software multicast queue */
1436 if (ismcast)
1437 txq = &avp->av_mcastq;
1438
1439 /*
1440 * XXX This likely means that if there's a station in power
1441 * save mode, we won't be doing any kind of aggregation towards
1442 * anyone. This is likely a very suboptimal way of dealing
1443 * with things.
1444 */
1445 if ((! is_ampdu) && (vap->iv_ps_sta || avp->av_mcastq.axq_depth))
1446 txq = &avp->av_mcastq;
1447
1448 /* Do the generic frame setup */
1449 /* XXX should just bzero the bf_state? */
1450 bf->bf_state.bfs_dobaw = 0;
1451 bf->bf_state.bfs_seqno_assigned = 0;
1452 bf->bf_state.bfs_need_seqno = 0;
1453 bf->bf_state.bfs_seqno = -1; /* XXX debugging */
1450
1451 /* A-MPDU TX? Manually set sequence number */
1452 /* Don't do it whilst pending; the net80211 layer still assigns them */
1453 /* XXX do we need locking here? */
1454 if (is_ampdu_tx) {
1455 ATH_TXQ_LOCK(txq);
1456 /*
1457 * Always call; this function will
1458 * handle making sure that null data frames
1459 * don't get a sequence number from the current
1460 * TID and thus mess with the BAW.
1461 */
1454
1455 /* A-MPDU TX? Manually set sequence number */
1456 /* Don't do it whilst pending; the net80211 layer still assigns them */
1457 /* XXX do we need locking here? */
1458 if (is_ampdu_tx) {
1459 ATH_TXQ_LOCK(txq);
1460 /*
1461 * Always call; this function will
1462 * handle making sure that null data frames
1463 * don't get a sequence number from the current
1464 * TID and thus mess with the BAW.
1465 */
1462 seqno = ath_tx_tid_seqno_assign(sc, ni, bf, m0);
1463 if (IEEE80211_QOS_HAS_SEQ(wh) &&
1464 subtype != IEEE80211_FC0_SUBTYPE_QOS_NULL) {
1466 //seqno = ath_tx_tid_seqno_assign(sc, ni, bf, m0);
1467 if (ath_tx_seqno_required(sc, ni, bf, m0)) {
1465 bf->bf_state.bfs_dobaw = 1;
1468 bf->bf_state.bfs_dobaw = 1;
1469 bf->bf_state.bfs_need_seqno = 1;
1466 }
1467 ATH_TXQ_UNLOCK(txq);
1470 }
1471 ATH_TXQ_UNLOCK(txq);
1472 } else {
1473 /* No AMPDU TX, we've been assigned a sequence number. */
1474 if (IEEE80211_QOS_HAS_SEQ(wh)) {
1475 bf->bf_state.bfs_seqno_assigned = 1;
1476 bf->bf_state.bfs_seqno =
1477 M_SEQNO_GET(m0) << IEEE80211_SEQ_SEQ_SHIFT;
1478 }
1468 }
1469
1470 /*
1471 * If needed, the sequence number has been assigned.
1472 * Squirrel it away somewhere easy to get to.
1473 */
1479 }
1480
1481 /*
1482 * If needed, the sequence number has been assigned.
1483 * Squirrel it away somewhere easy to get to.
1484 */
1474 bf->bf_state.bfs_seqno = M_SEQNO_GET(m0) << IEEE80211_SEQ_SEQ_SHIFT;
1485 //bf->bf_state.bfs_seqno = M_SEQNO_GET(m0) << IEEE80211_SEQ_SEQ_SHIFT;
1475
1476 /* Is ampdu pending? fetch the seqno and print it out */
1477 if (is_ampdu_pending)
1478 DPRINTF(sc, ATH_DEBUG_SW_TX,
1479 "%s: tid %d: ampdu pending, seqno %d\n",
1480 __func__, tid, M_SEQNO_GET(m0));
1481
1482 /* This also sets up the DMA map */
1483 r = ath_tx_normal_setup(sc, ni, bf, m0);
1484
1485 if (r != 0)
1486 return r;
1487
1488 /* At this point m0 could have changed! */
1489 m0 = bf->bf_m;
1490
1486
1487 /* Is ampdu pending? fetch the seqno and print it out */
1488 if (is_ampdu_pending)
1489 DPRINTF(sc, ATH_DEBUG_SW_TX,
1490 "%s: tid %d: ampdu pending, seqno %d\n",
1491 __func__, tid, M_SEQNO_GET(m0));
1492
1493 /* This also sets up the DMA map */
1494 r = ath_tx_normal_setup(sc, ni, bf, m0);
1495
1496 if (r != 0)
1497 return r;
1498
1499 /* At this point m0 could have changed! */
1500 m0 = bf->bf_m;
1501
1502 DPRINTF(sc, ATH_DEBUG_SW_TX,
1503 "%s: DONE: bf=%p, tid=%d, ac=%d, is_ampdu=%d, dobaw=%d, seqno=%d\n",
1504 __func__, bf, tid, pri, is_ampdu, bf->bf_state.bfs_dobaw, M_SEQNO_GET(m0));
1505
1491#if 1
1492 /*
1493 * If it's a multicast frame, do a direct-dispatch to the
1494 * destination hardware queue. Don't bother software
1495 * queuing it.
1496 */
1497 /*
1498 * If it's a BAR frame, do a direct dispatch to the
1499 * destination hardware queue. Don't bother software
1500 * queuing it, as the TID will now be paused.
1501 * Sending a BAR frame can occur from the net80211 txa timer
1502 * (ie, retries) or from the ath txtask (completion call.)
1503 * It queues directly to hardware because the TID is paused
1504 * at this point (and won't be unpaused until the BAR has
1505 * either been TXed successfully or max retries has been
1506 * reached.)
1507 */
1508 if (txq == &avp->av_mcastq) {
1506#if 1
1507 /*
1508 * If it's a multicast frame, do a direct-dispatch to the
1509 * destination hardware queue. Don't bother software
1510 * queuing it.
1511 */
1512 /*
1513 * If it's a BAR frame, do a direct dispatch to the
1514 * destination hardware queue. Don't bother software
1515 * queuing it, as the TID will now be paused.
1516 * Sending a BAR frame can occur from the net80211 txa timer
1517 * (ie, retries) or from the ath txtask (completion call.)
1518 * It queues directly to hardware because the TID is paused
1519 * at this point (and won't be unpaused until the BAR has
1520 * either been TXed successfully or max retries has been
1521 * reached.)
1522 */
1523 if (txq == &avp->av_mcastq) {
1524 DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL,
1525 "%s: bf=%p: mcastq: TX'ing\n", __func__, bf);
1509 ATH_TXQ_LOCK(txq);
1510 ath_tx_xmit_normal(sc, txq, bf);
1511 ATH_TXQ_UNLOCK(txq);
1512 } else if (type == IEEE80211_FC0_TYPE_CTL &&
1513 subtype == IEEE80211_FC0_SUBTYPE_BAR) {
1514 DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL,
1515 "%s: BAR: TX'ing direct\n", __func__);
1516 ATH_TXQ_LOCK(txq);
1517 ath_tx_xmit_normal(sc, txq, bf);
1518 ATH_TXQ_UNLOCK(txq);
1519 } else {
1520 /* add to software queue */
1526 ATH_TXQ_LOCK(txq);
1527 ath_tx_xmit_normal(sc, txq, bf);
1528 ATH_TXQ_UNLOCK(txq);
1529 } else if (type == IEEE80211_FC0_TYPE_CTL &&
1530 subtype == IEEE80211_FC0_SUBTYPE_BAR) {
1531 DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL,
1532 "%s: BAR: TX'ing direct\n", __func__);
1533 ATH_TXQ_LOCK(txq);
1534 ath_tx_xmit_normal(sc, txq, bf);
1535 ATH_TXQ_UNLOCK(txq);
1536 } else {
1537 /* add to software queue */
1538 DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL,
1539 "%s: bf=%p: swq: TX'ing\n", __func__, bf);
1521 ath_tx_swq(sc, ni, txq, bf);
1522 }
1523#else
1524 /*
1525 * For now, since there's no software queue,
1526 * direct-dispatch to the hardware.
1527 */
1528 ATH_TXQ_LOCK(txq);

--- 432 unchanged lines hidden (view full) ---

1961 int index, cindex;
1962 struct ieee80211_tx_ampdu *tap;
1963
1964 ATH_TXQ_LOCK_ASSERT(sc->sc_ac2q[tid->ac]);
1965
1966 if (bf->bf_state.bfs_isretried)
1967 return;
1968
1540 ath_tx_swq(sc, ni, txq, bf);
1541 }
1542#else
1543 /*
1544 * For now, since there's no software queue,
1545 * direct-dispatch to the hardware.
1546 */
1547 ATH_TXQ_LOCK(txq);

--- 432 unchanged lines hidden (view full) ---

1980 int index, cindex;
1981 struct ieee80211_tx_ampdu *tap;
1982
1983 ATH_TXQ_LOCK_ASSERT(sc->sc_ac2q[tid->ac]);
1984
1985 if (bf->bf_state.bfs_isretried)
1986 return;
1987
1988 /*
1989 * If this occurs we're in a lot of trouble. We should try to
1990 * recover from this without the session hanging?
1991 */
1992 if (! bf->bf_state.bfs_seqno_assigned) {
1993 device_printf(sc->sc_dev,
1994 "%s: bf=%p, seqno_assigned is 0?!\n", __func__, bf);
1995 return;
1996 }
1997
1969 tap = ath_tx_get_tx_tid(an, tid->tid);
1970
1971 if (bf->bf_state.bfs_addedbaw)
1972 device_printf(sc->sc_dev,
1998 tap = ath_tx_get_tx_tid(an, tid->tid);
1999
2000 if (bf->bf_state.bfs_addedbaw)
2001 device_printf(sc->sc_dev,
1973 "%s: re-added? tid=%d, seqno %d; window %d:%d; "
2002 "%s: re-added? bf=%p, tid=%d, seqno %d; window %d:%d; "
1974 "baw head=%d tail=%d\n",
2003 "baw head=%d tail=%d\n",
1975 __func__, tid->tid, SEQNO(bf->bf_state.bfs_seqno),
2004 __func__, bf, tid->tid, SEQNO(bf->bf_state.bfs_seqno),
1976 tap->txa_start, tap->txa_wnd, tid->baw_head,
1977 tid->baw_tail);
1978
1979 /*
2005 tap->txa_start, tap->txa_wnd, tid->baw_head,
2006 tid->baw_tail);
2007
2008 /*
2009 * Verify that the given sequence number is not outside of the
2010 * BAW. Complain loudly if that's the case.
2011 */
2012 if (! BAW_WITHIN(tap->txa_start, tap->txa_wnd,
2013 SEQNO(bf->bf_state.bfs_seqno))) {
2014 device_printf(sc->sc_dev,
2015 "%s: bf=%p: outside of BAW?? tid=%d, seqno %d; window %d:%d; "
2016 "baw head=%d tail=%d\n",
2017 __func__, bf, tid->tid, SEQNO(bf->bf_state.bfs_seqno),
2018 tap->txa_start, tap->txa_wnd, tid->baw_head,
2019 tid->baw_tail);
2020
2021 }
2022
2023 /*
1980 * ni->ni_txseqs[] is the currently allocated seqno.
1981 * the txa state contains the current baw start.
1982 */
1983 index = ATH_BA_INDEX(tap->txa_start, SEQNO(bf->bf_state.bfs_seqno));
1984 cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
1985 DPRINTF(sc, ATH_DEBUG_SW_TX_BAW,
2024 * ni->ni_txseqs[] is the currently allocated seqno.
2025 * the txa state contains the current baw start.
2026 */
2027 index = ATH_BA_INDEX(tap->txa_start, SEQNO(bf->bf_state.bfs_seqno));
2028 cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
2029 DPRINTF(sc, ATH_DEBUG_SW_TX_BAW,
1986 "%s: tid=%d, seqno %d; window %d:%d; index=%d cindex=%d "
2030 "%s: bf=%p, tid=%d, seqno %d; window %d:%d; index=%d cindex=%d "
1987 "baw head=%d tail=%d\n",
2031 "baw head=%d tail=%d\n",
1988 __func__, tid->tid, SEQNO(bf->bf_state.bfs_seqno),
2032 __func__, bf, tid->tid, SEQNO(bf->bf_state.bfs_seqno),
1989 tap->txa_start, tap->txa_wnd, index, cindex, tid->baw_head,
1990 tid->baw_tail);
1991
1992
1993#if 0
1994 assert(tid->tx_buf[cindex] == NULL);
1995#endif
1996 if (tid->tx_buf[cindex] != NULL) {

--- 86 unchanged lines hidden (view full) ---

2083
2084 ATH_TXQ_LOCK_ASSERT(sc->sc_ac2q[tid->ac]);
2085
2086 tap = ath_tx_get_tx_tid(an, tid->tid);
2087 index = ATH_BA_INDEX(tap->txa_start, seqno);
2088 cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
2089
2090 DPRINTF(sc, ATH_DEBUG_SW_TX_BAW,
2033 tap->txa_start, tap->txa_wnd, index, cindex, tid->baw_head,
2034 tid->baw_tail);
2035
2036
2037#if 0
2038 assert(tid->tx_buf[cindex] == NULL);
2039#endif
2040 if (tid->tx_buf[cindex] != NULL) {

--- 86 unchanged lines hidden (view full) ---

2127
2128 ATH_TXQ_LOCK_ASSERT(sc->sc_ac2q[tid->ac]);
2129
2130 tap = ath_tx_get_tx_tid(an, tid->tid);
2131 index = ATH_BA_INDEX(tap->txa_start, seqno);
2132 cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
2133
2134 DPRINTF(sc, ATH_DEBUG_SW_TX_BAW,
2091 "%s: tid=%d, baw=%d:%d, seqno=%d, index=%d, cindex=%d, "
2135 "%s: bf=%p: tid=%d, baw=%d:%d, seqno=%d, index=%d, cindex=%d, "
2092 "baw head=%d, tail=%d\n",
2136 "baw head=%d, tail=%d\n",
2093 __func__, tid->tid, tap->txa_start, tap->txa_wnd, seqno, index,
2137 __func__, bf, tid->tid, tap->txa_start, tap->txa_wnd, seqno, index,
2094 cindex, tid->baw_head, tid->baw_tail);
2095
2096 /*
2097 * If this occurs then we have a big problem - something else
2098 * has slid tap->txa_start along without updating the BAW
2099 * tracking start/end pointers. Thus the TX BAW state is now
2100 * completely busted.
2101 *

--- 64 unchanged lines hidden (view full) ---

2166 if (tid->sched == 0)
2167 return;
2168
2169 tid->sched = 0;
2170 TAILQ_REMOVE(&txq->axq_tidq, tid, axq_qelem);
2171}
2172
2173/*
2138 cindex, tid->baw_head, tid->baw_tail);
2139
2140 /*
2141 * If this occurs then we have a big problem - something else
2142 * has slid tap->txa_start along without updating the BAW
2143 * tracking start/end pointers. Thus the TX BAW state is now
2144 * completely busted.
2145 *

--- 64 unchanged lines hidden (view full) ---

2210 if (tid->sched == 0)
2211 return;
2212
2213 tid->sched = 0;
2214 TAILQ_REMOVE(&txq->axq_tidq, tid, axq_qelem);
2215}
2216
2217/*
2218 * Return whether a sequence number is actually required.
2219 *
2220 * A sequence number must only be allocated at the time that a frame
2221 * is considered for addition to the BAW/aggregate and being TXed.
2222 * The sequence number must not be allocated before the frame
2223 * is added to the BAW (protected by the same lock instance)
2224 * otherwise a the multi-entrant TX path may result in a later seqno
2225 * being added to the BAW first. The subsequent addition of the
2226 * earlier seqno would then not go into the BAW as it's now outside
2227 * of said BAW.
2228 *
2229 * This routine is used by ath_tx_start() to mark whether the frame
2230 * should get a sequence number before adding it to the BAW.
2231 *
2232 * Then the actual aggregate TX routines will check whether this
2233 * flag is set and if the frame needs to go into the BAW, it'll
2234 * have a sequence number allocated for it.
2235 */
2236static int
2237ath_tx_seqno_required(struct ath_softc *sc, struct ieee80211_node *ni,
2238 struct ath_buf *bf, struct mbuf *m0)
2239{
2240 const struct ieee80211_frame *wh;
2241 uint8_t subtype;
2242
2243 wh = mtod(m0, const struct ieee80211_frame *);
2244 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
2245
2246 /* XXX assert txq lock */
2247 /* XXX assert ampdu is set */
2248
2249 return ((IEEE80211_QOS_HAS_SEQ(wh) &&
2250 subtype != IEEE80211_FC0_SUBTYPE_QOS_NULL));
2251}
2252
2253/*
2174 * Assign a sequence number manually to the given frame.
2175 *
2176 * This should only be called for A-MPDU TX frames.
2254 * Assign a sequence number manually to the given frame.
2255 *
2256 * This should only be called for A-MPDU TX frames.
2257 *
2258 * If this is called after the initial frame setup, make sure you've flushed
2259 * the DMA map or you'll risk sending stale data to the NIC. This routine
2260 * updates the actual frame contents with the relevant seqno.
2177 */
2261 */
2178static ieee80211_seq
2262int
2179ath_tx_tid_seqno_assign(struct ath_softc *sc, struct ieee80211_node *ni,
2180 struct ath_buf *bf, struct mbuf *m0)
2181{
2182 struct ieee80211_frame *wh;
2183 int tid, pri;
2184 ieee80211_seq seqno;
2185 uint8_t subtype;
2186
2187 /* TID lookup */
2188 wh = mtod(m0, struct ieee80211_frame *);
2189 pri = M_WME_GETAC(m0); /* honor classification */
2190 tid = WME_AC_TO_TID(pri);
2263ath_tx_tid_seqno_assign(struct ath_softc *sc, struct ieee80211_node *ni,
2264 struct ath_buf *bf, struct mbuf *m0)
2265{
2266 struct ieee80211_frame *wh;
2267 int tid, pri;
2268 ieee80211_seq seqno;
2269 uint8_t subtype;
2270
2271 /* TID lookup */
2272 wh = mtod(m0, struct ieee80211_frame *);
2273 pri = M_WME_GETAC(m0); /* honor classification */
2274 tid = WME_AC_TO_TID(pri);
2191 DPRINTF(sc, ATH_DEBUG_SW_TX, "%s: pri=%d, tid=%d, qos has seq=%d\n",
2192 __func__, pri, tid, IEEE80211_QOS_HAS_SEQ(wh));
2275 DPRINTF(sc, ATH_DEBUG_SW_TX,
2276 "%s: bf=%p, pri=%d, tid=%d, qos has seq=%d\n",
2277 __func__, bf, pri, tid, IEEE80211_QOS_HAS_SEQ(wh));
2193
2278
2279 if (! bf->bf_state.bfs_need_seqno) {
2280 device_printf(sc->sc_dev, "%s: bf=%p: need_seqno not set?!\n",
2281 __func__, bf);
2282 return -1;
2283 }
2284 /* XXX check for bfs_need_seqno? */
2285 if (bf->bf_state.bfs_seqno_assigned) {
2286 device_printf(sc->sc_dev,
2287 "%s: bf=%p: seqno already assigned (%d)?!\n",
2288 __func__, bf, SEQNO(bf->bf_state.bfs_seqno));
2289 return bf->bf_state.bfs_seqno >> IEEE80211_SEQ_SEQ_SHIFT;
2290 }
2291
2194 /* XXX Is it a control frame? Ignore */
2195
2196 /* Does the packet require a sequence number? */
2197 if (! IEEE80211_QOS_HAS_SEQ(wh))
2198 return -1;
2199
2200 /*
2201 * Is it a QOS NULL Data frame? Give it a sequence number from

--- 10 unchanged lines hidden (view full) ---

2212 INCR(ni->ni_txseqs[IEEE80211_NONQOS_TID], IEEE80211_SEQ_RANGE);
2213 } else {
2214 /* Manually assign sequence number */
2215 seqno = ni->ni_txseqs[tid];
2216 INCR(ni->ni_txseqs[tid], IEEE80211_SEQ_RANGE);
2217 }
2218 *(uint16_t *)&wh->i_seq[0] = htole16(seqno << IEEE80211_SEQ_SEQ_SHIFT);
2219 M_SEQNO_SET(m0, seqno);
2292 /* XXX Is it a control frame? Ignore */
2293
2294 /* Does the packet require a sequence number? */
2295 if (! IEEE80211_QOS_HAS_SEQ(wh))
2296 return -1;
2297
2298 /*
2299 * Is it a QOS NULL Data frame? Give it a sequence number from

--- 10 unchanged lines hidden (view full) ---

2310 INCR(ni->ni_txseqs[IEEE80211_NONQOS_TID], IEEE80211_SEQ_RANGE);
2311 } else {
2312 /* Manually assign sequence number */
2313 seqno = ni->ni_txseqs[tid];
2314 INCR(ni->ni_txseqs[tid], IEEE80211_SEQ_RANGE);
2315 }
2316 *(uint16_t *)&wh->i_seq[0] = htole16(seqno << IEEE80211_SEQ_SEQ_SHIFT);
2317 M_SEQNO_SET(m0, seqno);
2318 bf->bf_state.bfs_seqno = seqno << IEEE80211_SEQ_SEQ_SHIFT;
2319 bf->bf_state.bfs_seqno_assigned = 1;
2220
2221 /* Return so caller can do something with it if needed */
2320
2321 /* Return so caller can do something with it if needed */
2222 DPRINTF(sc, ATH_DEBUG_SW_TX, "%s: -> seqno=%d\n", __func__, seqno);
2322 DPRINTF(sc, ATH_DEBUG_SW_TX, "%s: bf=%p: -> seqno=%d\n",
2323 __func__,
2324 bf,
2325 seqno);
2223 return seqno;
2224}
2225
2226/*
2227 * Attempt to direct dispatch an aggregate frame to hardware.
2228 * If the frame is out of BAW, queue.
2229 * Otherwise, schedule it as a single frame.
2230 */
2231static void
2232ath_tx_xmit_aggr(struct ath_softc *sc, struct ath_node *an, struct ath_buf *bf)
2233{
2326 return seqno;
2327}
2328
2329/*
2330 * Attempt to direct dispatch an aggregate frame to hardware.
2331 * If the frame is out of BAW, queue.
2332 * Otherwise, schedule it as a single frame.
2333 */
2334static void
2335ath_tx_xmit_aggr(struct ath_softc *sc, struct ath_node *an, struct ath_buf *bf)
2336{
2337 struct ieee80211_node *ni = &an->an_node;
2234 struct ath_tid *tid = &an->an_tid[bf->bf_state.bfs_tid];
2235 struct ath_txq *txq = bf->bf_state.bfs_txq;
2236 struct ieee80211_tx_ampdu *tap;
2338 struct ath_tid *tid = &an->an_tid[bf->bf_state.bfs_tid];
2339 struct ath_txq *txq = bf->bf_state.bfs_txq;
2340 struct ieee80211_tx_ampdu *tap;
2341 int seqno;
2237
2238 ATH_TXQ_LOCK_ASSERT(txq);
2239
2240 tap = ath_tx_get_tx_tid(an, tid->tid);
2241
2242 /* paused? queue */
2243 if (tid->paused) {
2244 ATH_TXQ_INSERT_TAIL(tid, bf, bf_list);
2245 return;
2246 }
2247
2342
2343 ATH_TXQ_LOCK_ASSERT(txq);
2344
2345 tap = ath_tx_get_tx_tid(an, tid->tid);
2346
2347 /* paused? queue */
2348 if (tid->paused) {
2349 ATH_TXQ_INSERT_TAIL(tid, bf, bf_list);
2350 return;
2351 }
2352
2353 /*
2354 * TODO: If it's _before_ the BAW left edge, complain very loudly.
2355 * This means something (else) has slid the left edge along
2356 * before we got a chance to be TXed.
2357 */
2358
2359 /*
2360 * Is there space in this BAW for another frame?
2361 * If not, don't bother trying to schedule it; just
2362 * throw it back on the queue.
2363 *
2364 * If we allocate the sequence number before we add
2365 * it to the BAW, we risk racing with another TX
2366 * thread that gets in a frame into the BAW with
2367 * seqno greater than ours. We'd then fail the
2368 * below check and throw the frame on the tail of
2369 * the queue. The sender would then have a hole.
2370 *
2371 * XXX again, we're protecting ni->ni_txseqs[tid]
2372 * behind this hardware TXQ lock, like the rest of
2373 * the TIDs that map to it. Ugh.
2374 */
2375 if (bf->bf_state.bfs_dobaw) {
2376 if (! BAW_WITHIN(tap->txa_start, tap->txa_wnd,
2377 ni->ni_txseqs[bf->bf_state.bfs_tid])) {
2378 ATH_TXQ_INSERT_TAIL(tid, bf, bf_list);
2379 ath_tx_tid_sched(sc, tid);
2380 return;
2381 }
2382 if (! bf->bf_state.bfs_seqno_assigned) {
2383 seqno = ath_tx_tid_seqno_assign(sc, ni, bf, bf->bf_m);
2384 if (seqno < 0) {
2385 device_printf(sc->sc_dev,
2386 "%s: bf=%p, huh, seqno=-1?\n",
2387 __func__,
2388 bf);
2389 /* XXX what can we even do here? */
2390 }
2391 /* Flush seqno update to RAM */
2392 /*
2393 * XXX This is required because the dmasetup
2394 * XXX is done early rather than at dispatch
2395 * XXX time. Ew, we should fix this!
2396 */
2397 bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap,
2398 BUS_DMASYNC_PREWRITE);
2399 }
2400 }
2401
2248 /* outside baw? queue */
2249 if (bf->bf_state.bfs_dobaw &&
2250 (! BAW_WITHIN(tap->txa_start, tap->txa_wnd,
2251 SEQNO(bf->bf_state.bfs_seqno)))) {
2402 /* outside baw? queue */
2403 if (bf->bf_state.bfs_dobaw &&
2404 (! BAW_WITHIN(tap->txa_start, tap->txa_wnd,
2405 SEQNO(bf->bf_state.bfs_seqno)))) {
2406 device_printf(sc->sc_dev,
2407 "%s: bf=%p, shouldn't be outside BAW now?!\n",
2408 __func__,
2409 bf);
2252 ATH_TXQ_INSERT_TAIL(tid, bf, bf_list);
2253 ath_tx_tid_sched(sc, tid);
2254 return;
2255 }
2256
2257 /* Direct dispatch to hardware */
2258 ath_tx_do_ratelookup(sc, bf);
2259 ath_tx_rate_fill_rcflags(sc, bf);

--- 38 unchanged lines hidden (view full) ---

2298 struct mbuf *m0 = bf->bf_m;
2299
2300 /* Fetch the TID - non-QoS frames get assigned to TID 16 */
2301 wh = mtod(m0, struct ieee80211_frame *);
2302 pri = ath_tx_getac(sc, m0);
2303 tid = ath_tx_gettid(sc, m0);
2304 atid = &an->an_tid[tid];
2305
2410 ATH_TXQ_INSERT_TAIL(tid, bf, bf_list);
2411 ath_tx_tid_sched(sc, tid);
2412 return;
2413 }
2414
2415 /* Direct dispatch to hardware */
2416 ath_tx_do_ratelookup(sc, bf);
2417 ath_tx_rate_fill_rcflags(sc, bf);

--- 38 unchanged lines hidden (view full) ---

2456 struct mbuf *m0 = bf->bf_m;
2457
2458 /* Fetch the TID - non-QoS frames get assigned to TID 16 */
2459 wh = mtod(m0, struct ieee80211_frame *);
2460 pri = ath_tx_getac(sc, m0);
2461 tid = ath_tx_gettid(sc, m0);
2462 atid = &an->an_tid[tid];
2463
2306 DPRINTF(sc, ATH_DEBUG_SW_TX, "%s: bf=%p, pri=%d, tid=%d, qos=%d\n",
2307 __func__, bf, pri, tid, IEEE80211_QOS_HAS_SEQ(wh));
2464 DPRINTF(sc, ATH_DEBUG_SW_TX, "%s: bf=%p, pri=%d, tid=%d, qos=%d, seqno=%d\n",
2465 __func__, bf, pri, tid, IEEE80211_QOS_HAS_SEQ(wh), SEQNO(bf->bf_state.bfs_seqno));
2308
2309 /* Set local packet state, used to queue packets to hardware */
2310 bf->bf_state.bfs_tid = tid;
2311 bf->bf_state.bfs_txq = txq;
2312 bf->bf_state.bfs_pri = pri;
2313
2314 /*
2315 * If the hardware queue isn't busy, queue it directly.
2316 * If the hardware queue is busy, queue it.
2317 * If the TID is paused or the traffic it outside BAW, software
2318 * queue it.
2319 */
2320 ATH_TXQ_LOCK(txq);
2321 if (atid->paused) {
2322 /* TID is paused, queue */
2466
2467 /* Set local packet state, used to queue packets to hardware */
2468 bf->bf_state.bfs_tid = tid;
2469 bf->bf_state.bfs_txq = txq;
2470 bf->bf_state.bfs_pri = pri;
2471
2472 /*
2473 * If the hardware queue isn't busy, queue it directly.
2474 * If the hardware queue is busy, queue it.
2475 * If the TID is paused or the traffic it outside BAW, software
2476 * queue it.
2477 */
2478 ATH_TXQ_LOCK(txq);
2479 if (atid->paused) {
2480 /* TID is paused, queue */
2323 DPRINTF(sc, ATH_DEBUG_SW_TX, "%s: paused\n", __func__);
2481 DPRINTF(sc, ATH_DEBUG_SW_TX, "%s: bf=%p: paused\n", __func__, bf);
2324 ATH_TXQ_INSERT_TAIL(atid, bf, bf_list);
2325 } else if (ath_tx_ampdu_pending(sc, an, tid)) {
2326 /* AMPDU pending; queue */
2482 ATH_TXQ_INSERT_TAIL(atid, bf, bf_list);
2483 } else if (ath_tx_ampdu_pending(sc, an, tid)) {
2484 /* AMPDU pending; queue */
2327 DPRINTF(sc, ATH_DEBUG_SW_TX, "%s: pending\n", __func__);
2485 DPRINTF(sc, ATH_DEBUG_SW_TX, "%s: bf=%p: pending\n", __func__, bf);
2328 ATH_TXQ_INSERT_TAIL(atid, bf, bf_list);
2329 /* XXX sched? */
2330 } else if (ath_tx_ampdu_running(sc, an, tid)) {
2331 /* AMPDU running, attempt direct dispatch if possible */
2332 if (txq->axq_depth < sc->sc_hwq_limit) {
2486 ATH_TXQ_INSERT_TAIL(atid, bf, bf_list);
2487 /* XXX sched? */
2488 } else if (ath_tx_ampdu_running(sc, an, tid)) {
2489 /* AMPDU running, attempt direct dispatch if possible */
2490 if (txq->axq_depth < sc->sc_hwq_limit) {
2333 ath_tx_xmit_aggr(sc, an, bf);
2334 DPRINTF(sc, ATH_DEBUG_SW_TX,
2491 DPRINTF(sc, ATH_DEBUG_SW_TX,
2335 "%s: xmit_aggr\n",
2336 __func__);
2492 "%s: bf=%p: xmit_aggr\n",
2493 __func__, bf);
2494 ath_tx_xmit_aggr(sc, an, bf);
2337 } else {
2338 DPRINTF(sc, ATH_DEBUG_SW_TX,
2495 } else {
2496 DPRINTF(sc, ATH_DEBUG_SW_TX,
2339 "%s: ampdu; swq'ing\n",
2340 __func__);
2497 "%s: bf=%p: ampdu; swq'ing\n",
2498 __func__, bf);
2341 ATH_TXQ_INSERT_TAIL(atid, bf, bf_list);
2342 ath_tx_tid_sched(sc, atid);
2343 }
2344 } else if (txq->axq_depth < sc->sc_hwq_limit) {
2345 /* AMPDU not running, attempt direct dispatch */
2499 ATH_TXQ_INSERT_TAIL(atid, bf, bf_list);
2500 ath_tx_tid_sched(sc, atid);
2501 }
2502 } else if (txq->axq_depth < sc->sc_hwq_limit) {
2503 /* AMPDU not running, attempt direct dispatch */
2346 DPRINTF(sc, ATH_DEBUG_SW_TX, "%s: xmit_normal\n", __func__);
2504 DPRINTF(sc, ATH_DEBUG_SW_TX, "%s: bf=%p: xmit_normal\n", __func__, bf);
2347 ath_tx_xmit_normal(sc, txq, bf);
2348 } else {
2349 /* Busy; queue */
2505 ath_tx_xmit_normal(sc, txq, bf);
2506 } else {
2507 /* Busy; queue */
2350 DPRINTF(sc, ATH_DEBUG_SW_TX, "%s: swq'ing\n", __func__);
2508 DPRINTF(sc, ATH_DEBUG_SW_TX, "%s: bf=%p: swq'ing\n", __func__, bf);
2351 ATH_TXQ_INSERT_TAIL(atid, bf, bf_list);
2352 ath_tx_tid_sched(sc, atid);
2353 }
2354 ATH_TXQ_UNLOCK(txq);
2355}
2356
2357/*
2358 * Do the basic frame setup stuff that's required before the frame

--- 114 unchanged lines hidden (view full) ---

2473 for (;;) {
2474 bf = TAILQ_FIRST(&tid->axq_q);
2475 if (bf == NULL) {
2476 break;
2477 }
2478
2479 if (t == 0) {
2480 device_printf(sc->sc_dev,
2509 ATH_TXQ_INSERT_TAIL(atid, bf, bf_list);
2510 ath_tx_tid_sched(sc, atid);
2511 }
2512 ATH_TXQ_UNLOCK(txq);
2513}
2514
2515/*
2516 * Do the basic frame setup stuff that's required before the frame

--- 114 unchanged lines hidden (view full) ---

2631 for (;;) {
2632 bf = TAILQ_FIRST(&tid->axq_q);
2633 if (bf == NULL) {
2634 break;
2635 }
2636
2637 if (t == 0) {
2638 device_printf(sc->sc_dev,
2481 "%s: node %p: tid %d: txq_depth=%d, "
2639 "%s: node %p: bf=%p: tid %d: txq_depth=%d, "
2482 "txq_aggr_depth=%d, sched=%d, paused=%d, "
2483 "hwq_depth=%d, incomp=%d, baw_head=%d, "
2484 "baw_tail=%d txa_start=%d, ni_txseqs=%d\n",
2640 "txq_aggr_depth=%d, sched=%d, paused=%d, "
2641 "hwq_depth=%d, incomp=%d, baw_head=%d, "
2642 "baw_tail=%d txa_start=%d, ni_txseqs=%d\n",
2485 __func__, ni, tid->tid, txq->axq_depth,
2643 __func__, ni, bf, tid->tid, txq->axq_depth,
2486 txq->axq_aggr_depth, tid->sched, tid->paused,
2487 tid->hwq_depth, tid->incomp, tid->baw_head,
2488 tid->baw_tail, tap == NULL ? -1 : tap->txa_start,
2489 ni->ni_txseqs[tid->tid]);
2490
2491 /* XXX Dump the frame, see what it is? */
2492 ieee80211_dump_pkt(ni->ni_ic,
2493 mtod(bf->bf_m, const uint8_t *),
2494 bf->bf_m->m_len, 0, -1);
2495
2644 txq->axq_aggr_depth, tid->sched, tid->paused,
2645 tid->hwq_depth, tid->incomp, tid->baw_head,
2646 tid->baw_tail, tap == NULL ? -1 : tap->txa_start,
2647 ni->ni_txseqs[tid->tid]);
2648
2649 /* XXX Dump the frame, see what it is? */
2650 ieee80211_dump_pkt(ni->ni_ic,
2651 mtod(bf->bf_m, const uint8_t *),
2652 bf->bf_m->m_len, 0, -1);
2653
2496 t = 1;
2654 //t = 1;
2497 }
2498
2499
2500 /*
2501 * If the current TID is running AMPDU, update
2502 * the BAW.
2503 */
2504 if (ath_tx_ampdu_running(sc, an, tid->tid) &&

--- 1537 unchanged lines hidden ---
2655 }
2656
2657
2658 /*
2659 * If the current TID is running AMPDU, update
2660 * the BAW.
2661 */
2662 if (ath_tx_ampdu_running(sc, an, tid->tid) &&

--- 1537 unchanged lines hidden ---