Date: Mon, 19 Sep 2011 08:01:21 +0000 (UTC) From: Adrian Chadd <adrian@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r225658 - user/adrian/if_ath_tx/sys/dev/ath Message-ID: <201109190801.p8J81LqW069708@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: adrian Date: Mon Sep 19 08:01:21 2011 New Revision: 225658 URL: http://svn.freebsd.org/changeset/base/225658 Log: First cut at enabling the TX of BAR frams. Currently ieee80211_send_bar() calls back into the driver via ic->ic_raw_xmit(). The driver has some special case code to directly dispatch BAR frames for this exact purpose. This means that the hardware TXQ lock is needed, so BAR frame TX must occur from _outside_ the TXQ lock. * Unlock the TXQ before attempting to send a BAR frame * Take a note of the txseq whilst inside the TXQ lock - although other contexts may allocate TX sequence numbers (and I'm about to stick that inside the TXQ lock too just to be safe), all frames from this point on have not yet attempted to be transmitted. So the TX sequence number at this point is fine as a left edge for the BAW. This has only received light testing due to some bugs I've introduced which make a fixed unicast rate no longer work (the multi-rate retry schedule is incorrectly being set.) This means that although I can trigger frame failure, it isn't predictable or guaranteed. I'll fix that in a subsequent commit and then properly test the aggregate and non-aggregate BAR pathways whilst traffic is ongoing. Modified: user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c Modified: user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c ============================================================================== --- user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c Mon Sep 19 05:12:53 2011 (r225657) +++ user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c Mon Sep 19 08:01:21 2011 (r225658) @@ -2648,6 +2648,7 @@ ath_tx_aggr_retry_unaggr(struct ath_soft int tid = bf->bf_state.bfs_tid; struct ath_tid *atid = &an->an_tid[tid]; struct ieee80211_tx_ampdu *tap; + int txseq; ATH_TXQ_LOCK(sc->sc_ac2q[atid->ac]); @@ -2694,11 +2695,18 @@ ath_tx_aggr_retry_unaggr(struct ath_soft * This'll end up going into net80211 and back out * again, via ic->ic_raw_xmit(). */ + txseq = ni->ni_txseqs[tid]; device_printf(sc->sc_dev, - "%s: TID %d: send BAR; seq %d\n", - __func__, tid, ni->ni_txseqs[tid]); -#if 0 - if (ieee80211_send_bar(ni, tap, ni->ni_txseqs[tid]) == 0) { + "%s: TID %d: send BAR; seq %d\n", __func__, tid, txseq); + ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); + /* + * It's ok to unlock it now (and it's required at + * the moment!) since we are purging "holes" in the + * tx sequence up to this point; any subsequent + * sequence numbers haven't been yet attempted to + * TX. + */ + if (ieee80211_send_bar(ni, tap, txseq) == 0) { /* * Pause the TID if this was successful. * An un-successful BAR TX would never call @@ -2711,10 +2719,8 @@ ath_tx_aggr_retry_unaggr(struct ath_soft "%s: TID %d: BAR TX failed\n", __func__, tid); } -#endif /* Free buffer, bf is free after this call */ - ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); ath_tx_default_comp(sc, bf, 0); return; } @@ -2844,16 +2850,35 @@ ath_tx_comp_aggr_error(struct ath_softc bf = bf_next; } + /* Prepend all frames to the beginning of the queue */ + while ((bf = TAILQ_LAST(&bf_q, ath_bufhead_s)) != NULL) { + TAILQ_REMOVE(&bf_q, bf, bf_list); + ATH_TXQ_INSERT_HEAD(tid, bf, bf_list); + } + + ath_tx_tid_sched(sc, tid); + /* * send bar if we dropped any frames + * + * Keep the txq lock held for now, as we need to ensure + * that ni_txseqs[] is consistent (as it's being updated + * in the ifnet TX context or raw TX context.) */ if (drops) { + int txseq = ni->ni_txseqs[tid->tid]; device_printf(sc->sc_dev, "%s: TID %d: send BAR; seq %d\n", - __func__, tid->tid, - ni->ni_txseqs[tid->tid]); -#if 0 - if (ieee80211_send_bar(ni, tap, ni->ni_txseqs[tid->tid]) == 0) { + __func__, tid->tid, txseq); + ATH_TXQ_UNLOCK(sc->sc_ac2q[tid->ac]); + /* + * It's ok to unlock it now (and it's required at + * the moment!) since we are purging "holes" in the + * tx sequence up to this point; any subsequent + * sequence numbers haven't been yet attempted to + * TX. + */ + if (ieee80211_send_bar(ni, tap, txseq) == 0) { /* * Pause the TID if this was successful. * An un-successful BAR TX would never call @@ -2866,23 +2891,17 @@ ath_tx_comp_aggr_error(struct ath_softc "%s: TID %d: BAR TX failed\n", __func__, tid->tid); } -#endif + } else { + ATH_TXQ_UNLOCK(sc->sc_ac2q[tid->ac]); } - /* Prepend all frames to the beginning of the queue */ - while ((bf = TAILQ_LAST(&bf_q, ath_bufhead_s)) != NULL) { - TAILQ_REMOVE(&bf_q, bf, bf_list); - ATH_TXQ_INSERT_HEAD(tid, bf, bf_list); - } - - ath_tx_tid_sched(sc, tid); - ATH_TXQ_UNLOCK(sc->sc_ac2q[tid->ac]); - /* Complete frames which errored out */ while ((bf = TAILQ_FIRST(&bf_cq)) != NULL) { TAILQ_REMOVE(&bf_cq, bf, bf_list); ath_tx_default_comp(sc, bf, 0); } + + } /* @@ -2957,6 +2976,7 @@ ath_tx_aggr_comp_aggr(struct ath_softc * int pktlen; /* XXX there's too much on the stack? */ struct ath_rc_series rc[4]; + int txseq; DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR, "%s: called; hwq_depth=%d\n", __func__, atid->hwq_depth); @@ -3092,7 +3112,15 @@ ath_tx_aggr_comp_aggr(struct ath_softc * bf = bf_next; } - /* Now that the BAW updates have been done, unlock */ + /* + * Now that the BAW updates have been done, unlock + * + * txseq is grabbed before the lock is released so we + * have a consistent view of what -was- in the BAW. + * Anything after this point will not yet have been + * TXed. + */ + txseq = ni->ni_txseqs[tid]; ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); if (nframes != nf) @@ -3107,12 +3135,13 @@ ath_tx_aggr_comp_aggr(struct ath_softc * if (fail == 0) ath_tx_update_ratectrl(sc, ni, rc, &ts, pktlen, nframes, nbad); -#if 0 /* * send bar if we dropped any frames */ if (drops) { - if (ieee80211_send_bar(ni, tap, ni->ni_txseqs[tid]) == 0) { + device_printf(sc->sc_dev, + "%s: TID %d: send BAR; seq %d\n", __func__, tid, txseq); + if (ieee80211_send_bar(ni, tap, txseq) == 0) { /* * Pause the TID if this was successful. * An un-successful BAR TX would never call @@ -3126,7 +3155,6 @@ ath_tx_aggr_comp_aggr(struct ath_softc * __func__, tid); } } -#endif /* Prepend all frames to the beginning of the queue */ ATH_TXQ_LOCK(sc->sc_ac2q[atid->ac]); @@ -3134,7 +3162,6 @@ ath_tx_aggr_comp_aggr(struct ath_softc * TAILQ_REMOVE(&bf_q, bf, bf_list); ATH_TXQ_INSERT_HEAD(atid, bf, bf_list); } - ath_tx_tid_sched(sc, atid); ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201109190801.p8J81LqW069708>