PERFORCE change 74079 for review

Sam Leffler sam at FreeBSD.org
Tue Mar 29 21:20:08 PST 2005


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

Change 74079 by sam at sam_ebb on 2005/03/30 05:19:40

	IFC ibss merge fixup
	add CTS extension for when bursting frames

Affected files ...

.. //depot/projects/wifi/sys/dev/ath/if_ath.c#78 edit

Differences ...

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

@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/ath/if_ath.c,v 1.77 2005/03/08 17:01:03 sam Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/ath/if_ath.c,v 1.81 2005/03/30 02:33:33 avatar Exp $");
 
 /*
  * Driver for the Atheros Wireless LAN controller.
@@ -2765,6 +2765,21 @@
 }
 
 /*
+ * Extend 15-bit time stamp from rx descriptor to
+ * a full 64-bit TSF using the current h/w TSF.
+ */
+static __inline u_int64_t
+ath_extend_tsf(struct ath_hal *ah, u_int32_t rstamp)
+{
+	u_int64_t tsf;
+
+	tsf = ath_hal_gettsf64(ah);
+	if ((tsf & 0x7fff) < rstamp)
+		tsf -= 0x8000;
+	return ((tsf &~ 0x7fff) | rstamp);
+}
+
+/*
  * Intercept management frames to collect beacon rssi data
  * and to do ibss merges.
  */
@@ -2788,10 +2803,7 @@
 	case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
 		if (ic->ic_opmode == IEEE80211_M_IBSS &&
 		    ic->ic_state == IEEE80211_S_RUN) {
-			struct ath_hal *ah = sc->sc_ah;
-			/* XXX extend rstamp */
-			u_int64_t tsf = ath_hal_gettsf64(ah);
-
+			u_int64_t tsf = ath_extend_tsf(sc->sc_ah, rstamp);
 			/*
 			 * Handle ibss merge as needed; check the tsf on the
 			 * frame before attempting the merge.  The 802.11 spec
@@ -2799,11 +2811,16 @@
 			 * the oldest station with the same ssid, where oldest
 			 * is determined by the tsf.  Note that hardware
 			 * reconfiguration happens through callback to
-			 * ath_newstate as the state machine will be go
-			 * from RUN -> RUN when this happens.
+			 * ath_newstate as the state machine will go from
+			 * RUN -> RUN when this happens.
 			 */
-			if (le64toh(ni->ni_tstamp.tsf) >= tsf)
+			if (le64toh(ni->ni_tstamp.tsf) >= tsf) {
+				DPRINTF(sc, ATH_DEBUG_STATE,
+				    "ibss merge, rstamp %u tsf %ju "
+				    "tstamp %ju\n", rstamp, (uintmax_t)tsf,
+				    (uintmax_t)ni->ni_tstamp.tsf);
 				(void) ieee80211_ibss_merge(ic, ni);
+			}
 		}
 		break;
 	}
@@ -3377,6 +3394,7 @@
 	struct ieee80211com *ic = &sc->sc_ic;
 	struct ath_hal *ah = sc->sc_ah;
 	struct ifnet *ifp = &sc->sc_if;
+	const struct chanAccParams *cap = &ic->ic_wme.wme_wmeChanParams;
 	int i, error, iswep, ismcast, keyix, hdrlen, pktlen, try0;
 	u_int8_t rix, txrate, ctsrate;
 	u_int8_t cix = 0xff;		/* NB: silence compiler */
@@ -3389,6 +3407,7 @@
 	HAL_BOOL shortPreamble;
 	struct ath_node *an;
 	struct mbuf *m;
+	u_int pri;
 
 	wh = mtod(m0, struct ieee80211_frame *);
 	iswep = wh->i_fc[1] & IEEE80211_FC1_WEP;
@@ -3467,10 +3486,9 @@
 	if (bf->bf_nseg > ATH_TXDESC) {		/* too many desc's, linearize */
 		sc->sc_stats.ast_tx_linear++;
 		m = ath_defrag(m0, M_DONTWAIT, ATH_TXDESC);
-		if (m0 == NULL) {
+		if (m == NULL) {
 			m_freem(m0);
 			sc->sc_stats.ast_tx_nombuf++;
-			m_freem(m0);
 			return ENOMEM;
 		}
 		m0 = m;
@@ -3538,9 +3556,9 @@
 		/* NB: force all management frames to highest queue */
 		if (ni->ni_flags & IEEE80211_NODE_QOS) {
 			/* NB: force all management frames to highest queue */
-			txq = sc->sc_ac2q[WME_AC_VO];
+			pri = WME_AC_VO;
 		} else
-			txq = sc->sc_ac2q[WME_AC_BE];
+			pri = WME_AC_BE;
 		flags |= HAL_TXDESC_INTREQ;	/* force interrupt */
 		break;
 	case IEEE80211_FC0_TYPE_CTL:
@@ -3554,9 +3572,9 @@
 		/* NB: force all ctl frames to highest queue */
 		if (ni->ni_flags & IEEE80211_NODE_QOS) {
 			/* NB: force all ctl frames to highest queue */
-			txq = sc->sc_ac2q[WME_AC_VO];
+			pri = WME_AC_VO;
 		} else
-			txq = sc->sc_ac2q[WME_AC_BE];
+			pri = WME_AC_BE;
 		flags |= HAL_TXDESC_INTREQ;	/* force interrupt */
 		break;
 	case IEEE80211_FC0_TYPE_DATA:
@@ -3572,14 +3590,13 @@
 		 * Default all non-QoS traffic to the best-effort queue.
 		 */
 		if (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS) {
-			u_int pri = M_WME_GETAC(m0);
-			txq = sc->sc_ac2q[pri];
-			if (ic->ic_wme.wme_wmeChanParams.cap_wmeParams[pri].wmep_noackPolicy) {
+			pri = M_WME_GETAC(m0);
+			if (cap->cap_wmeParams[pri].wmep_noackPolicy) {
 				flags |= HAL_TXDESC_NOACK;
 				sc->sc_stats.ast_tx_noack++;
 			}
 		} else
-			txq = sc->sc_ac2q[WME_AC_BE];
+			pri = WME_AC_BE;
 		break;
 	default:
 		if_printf(ifp, "bogus frame type 0x%x (%s)\n",
@@ -3588,6 +3605,7 @@
 		m_freem(m0);
 		return EIO;
 	}
+	txq = sc->sc_ac2q[pri];
 
 	/*
 	 * When servicing one or more stations in power-save mode
@@ -3778,22 +3796,38 @@
 			__func__, i, ds->ds_link, ds->ds_data,
 			ds->ds_ctl0, ds->ds_ctl1, ds->ds_hw[0], ds->ds_hw[1]);
 	}
-#if 0
-	if ((flags & (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA)) &&
-  	    !ath_hal_updateCTSForBursting(ah, ds 
-		     , txq->axq_linkbuf != NULL ?
+	if (flags & (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA)) {
+#define	CTS_DURATION \
+	ath_hal_computetxtime(ah, rt, IEEE80211_ACK_LEN, cix, AH_TRUE)
+		u_int32_t txopLimit = IEEE80211_TXOP_TO_US(
+			cap->cap_wmeParams[pri].wmep_txopLimit);
+		/*
+		 * When bursting, if RTS/CTS is to be used insure the
+		 * total duration does not exceed the limit imposed by
+		 * the WME parameters.  This is complicated as we need
+		 * to update the state of packets on the (live) hardware
+		 * queue.  The logic is buried in the hal because it's very
+		 * chip-specific.
+		 */
+		if (txopLimit != 0 &&
+		    ath_hal_updateCTSForBursting(ah, ds
+		    , txq->axq_linkbuf != NULL ?
 			txq->axq_linkbuf->bf_desc : NULL
-		     , txq->axq_lastdsWithCTS
-		     , txq->axq_gatingds
-		     , IEEE80211_TXOP_TO_US(ic->ic_chanParams.cap_wmeParams[skb->priority].wmep_txopLimit)
-		     , ath_hal_computetxtime(ah, rt, IEEE80211_ACK_LEN, cix, AH_TRUE))) {
-		ATH_TXQ_LOCK(txq);		     
-		txq->axq_lastdsWithCTS = ds;
-		/* set gating Desc to final desc */
-		txq->axq_gatingds = (struct ath_desc *)txq->axq_link;
-		ATH_TXQ_UNLOCK(txq);
+		    , txq->axq_lastdsWithCTS, txq->axq_gatingds
+		    , txopLimit, CTS_DURATION) == 0) {
+			/*
+			 * This descriptor falls in a new txop window, update
+			 * the descriptor pointers for the next packet that
+			 * needs similar treatment.
+			 */
+			ATH_TXQ_LOCK(txq);		     
+			txq->axq_lastdsWithCTS = ds;
+			/* set gating Desc to final desc */
+			txq->axq_gatingds = (struct ath_desc *)txq->axq_link;
+			ATH_TXQ_UNLOCK(txq);
+		}
+#undef CTS_DURATION
 	}
-#endif
 	/*
 	 * Insert the frame on the outbound list and
 	 * pass it on to the hardware.
@@ -3864,12 +3898,10 @@
 			ATH_TXQ_UNLOCK(txq);
 			break;
 		}
-#if 0
 		if (bf->bf_desc == txq->axq_lastdsWithCTS)
 			txq->axq_lastdsWithCTS = NULL;
 		if (ds == txq->axq_gatingds)
 			txq->axq_gatingds = NULL;
-#endif
 		ATH_TXQ_REMOVE_HEAD(txq, bf_list);
 		ATH_TXQ_UNLOCK(txq);
 


More information about the p4-projects mailing list