From owner-svn-src-user@FreeBSD.ORG Mon Sep 19 08:01:21 2011 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id BCB5A106566B; Mon, 19 Sep 2011 08:01:21 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id ABE3C8FC15; Mon, 19 Sep 2011 08:01:21 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p8J81LxO069710; Mon, 19 Sep 2011 08:01:21 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p8J81LqW069708; Mon, 19 Sep 2011 08:01:21 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201109190801.p8J81LqW069708@svn.freebsd.org> From: Adrian Chadd Date: Mon, 19 Sep 2011 08:01:21 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r225658 - user/adrian/if_ath_tx/sys/dev/ath X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 19 Sep 2011 08:01:21 -0000 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]);