PERFORCE change 136772 for review

Sam Leffler sam at FreeBSD.org
Mon Mar 3 23:44:41 UTC 2008


http://perforce.freebsd.org/chv.cgi?CH=136772

Change 136772 by sam at sam_ebb on 2008/03/03 23:44:02

	Fix power save mcast frame handling:
	o mark per-vap mcastq w/ the proper qnum so it's handled correctly
	  by ath_tx_handoff
	o mark frames with MORE_DATA as they are queued; this can result
	  in 1 frame being wrongly marked in very pathological cases but is
	  hard to avoid unless we want to calculate the air time coverage
	  for q'd frames to figure out where the hardware will cutoff our
	  bursting; in the case of a frame going out wrongly marked with
	  MORE_DATA this should just result in PS stations staying awake
	  for the remainder of the beacon interval (or less depending on
	  their implementation)

Affected files ...

.. //depot/projects/vap/sys/dev/ath/if_ath.c#38 edit
.. //depot/projects/vap/sys/dev/ath/if_athvar.h#18 edit

Differences ...

==== //depot/projects/vap/sys/dev/ath/if_ath.c#38 (text+ko) ====

@@ -906,8 +906,7 @@
 			 */
 			sc->sc_stagbeacons = 1;
 		}
-		STAILQ_INIT(&avp->av_mcastq.axq_q);
-		ATH_TXQ_LOCK_INIT(sc, &avp->av_mcastq);
+		ath_txq_init(sc, &avp->av_mcastq, ATH_TXQ_SWQ);
 	}
 
 	ic->ic_opmode = ic_opmode;
@@ -4407,8 +4406,8 @@
 	 * to avoid possible races.
 	 */
 	ATH_TXQ_LOCK(txq);
-	ATH_TXQ_INSERT_TAIL(txq, bf, bf_list);
 	if (txq->axq_qnum != ATH_TXQ_SWQ) {
+		ATH_TXQ_INSERT_TAIL(txq, bf, bf_list);
 		if (txq->axq_link == NULL) {
 			ath_hal_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
 			DPRINTF(sc, ATH_DEBUG_XMIT,
@@ -4425,8 +4424,20 @@
 		txq->axq_link = &bf->bf_desc[bf->bf_nseg - 1].ds_link;
 		ath_hal_txstart(ah, txq->axq_qnum);
 	} else {
-		if (txq->axq_link != NULL)
+		if (txq->axq_link != NULL) {
+			struct ath_buf *last = ATH_TXQ_LAST(txq);
+			struct ieee80211_frame *wh;
+
+			/* mark previous frame */
+			wh = mtod(last->bf_m, struct ieee80211_frame *);
+			wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA;
+			bus_dmamap_sync(sc->sc_dmat, last->bf_dmamap,
+			    BUS_DMASYNC_PREWRITE);
+
+			/* link descriptor */
 			*txq->axq_link = bf->bf_daddr;
+		}
+		ATH_TXQ_INSERT_TAIL(txq, bf, bf_list);
 		txq->axq_link = &bf->bf_desc[bf->bf_nseg - 1].ds_link;
 	}
 	ATH_TXQ_UNLOCK(txq);
@@ -4620,10 +4631,8 @@
 	 * queue (to prevent out of order delivery) multicast
 	 * frames must be buffered until after the beacon.
 	 */
-	if (ismcast && (vap->iv_ps_sta || avp->av_mcastq.axq_depth)) {
+	if (ismcast && (vap->iv_ps_sta || avp->av_mcastq.axq_depth))
 		txq = &avp->av_mcastq;
-		/* XXX? more bit in 802.11 frame header */
-	}
 
 	/*
 	 * Calculate miscellaneous flags.

==== //depot/projects/vap/sys/dev/ath/if_athvar.h#18 (text+ko) ====

@@ -180,6 +180,10 @@
 	STAILQ_REMOVE_HEAD(&(_tq)->axq_q, _field); \
 	(_tq)->axq_depth--; \
 } while (0)
+/* NB: this does not do the "head empty check" that STAILQ_LAST does */
+#define	ATH_TXQ_LAST(_tq) \
+	((struct ath_buf *)(void *) \
+	 ((char *)((_tq)->axq_q.stqh_last) - __offsetof(struct ath_buf, bf_list)))
 
 struct ath_vap {
 	struct ieee80211vap av_vap;	/* base class */


More information about the p4-projects mailing list