PERFORCE change 65687 for review

Sam Leffler sam at FreeBSD.org
Tue Nov 23 03:54:56 GMT 2004


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

Change 65687 by sam at sam_ebb on 2004/11/23 03:54:42

	checkpoint wme support (need to deal with CTS bursting)

Affected files ...

.. //depot/projects/wifi/sys/dev/ath/if_ath.c#27 edit
.. //depot/projects/wifi/sys/dev/ath/if_athvar.h#9 edit

Differences ...

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

@@ -134,6 +134,7 @@
 static void	ath_rx_proc(void *, int);
 static struct ath_txq *ath_txq_setup(struct ath_softc*, int qtype, int subtype);
 static int	ath_tx_setup(struct ath_softc *, int, int);
+static int	ath_wme_update(struct ieee80211com *);
 static void	ath_tx_cleanupq(struct ath_softc *, struct ath_txq *);
 static void	ath_tx_cleanup(struct ath_softc *);
 static int	ath_tx_start(struct ath_softc *, struct ieee80211_node *,
@@ -163,14 +164,6 @@
 static void	ath_bpfattach(struct ath_softc *);
 static void	ath_announce(struct ath_softc *);
 
-static const char *acnames[] = {
-	"WME_AC_BE",
-	"WME_AC_BK",
-	"WME_AC_VI",
-	"WME_AC_VO",
-	"WME_UPSD",
-};
-
 SYSCTL_DECL(_hw_ath);
 
 /* XXX validate sysctl values */
@@ -387,7 +380,7 @@
 	/* NB: insure BK queue is the lowest priority h/w queue */
 	if (!ath_tx_setup(sc, WME_AC_BK, HAL_WME_AC_BK)) {
 		if_printf(ifp, "unable to setup xmit queue for %s traffic!\n",
-			acnames[WME_AC_BK]);
+			ieee80211_wme_acnames[WME_AC_BK]);
 		error = EIO;
 		goto bad2;
 	}
@@ -459,6 +452,7 @@
 	ic->ic_reset = ath_reset;
 	ic->ic_newassoc = ath_newassoc;
 	ic->ic_updateslot = ath_updateslot;
+	ic->ic_wme.wme_update = ath_wme_update;
 	/* XXX not right but it's not used anywhere important */
 	ic->ic_phytype = IEEE80211_T_OFDM;
 	ic->ic_opmode = IEEE80211_M_STA;
@@ -502,7 +496,20 @@
 	sc->sc_hastpc = ath_hal_hastpc(ah);
 	if (sc->sc_hastpc || ath_hal_hastxpowlimit(ah))
 		ic->ic_caps |= IEEE80211_C_TXPMGT;
+
 	/*
+	 * Mark WME capability only if we have sufficient
+	 * hardware queues to do proper priority scheduling.
+	 */
+	if (sc->sc_ac2q[WME_AC_BE] != sc->sc_ac2q[WME_AC_BK])
+		ic->ic_caps |= IEEE80211_C_WME;
+	/*
+	 * Check for frame bursting capability.
+	 */
+	if (ath_hal_hasbursting(ah))
+		ic->ic_caps |= IEEE80211_C_BURST;
+
+	/*
 	 * Indicate we need the 802.11 header padded to a
 	 * 32-bit boundary for 4-address and QoS frames.
 	 */
@@ -1082,6 +1089,13 @@
 				ieee80211_pwrsave(ic, ni, m);
 				goto reclaim;
 			}
+			/* calculate priority so we can find the tx queue */
+			if (ieee80211_classify(ic, m, ni)) {
+				DPRINTF(sc, ATH_DEBUG_XMIT,
+					"%s: discard, classification failure\n",
+					__func__);
+				goto bad;
+			}
 			ifp->if_opackets++;
 			BPF_MTAP(ifp, m);
 			/*
@@ -2667,6 +2681,53 @@
 }
 
 /*
+ * Update WME parameters for a transmit queue.
+ */
+static int
+ath_txq_update(struct ath_softc *sc, int ac)
+{
+#define	ATH_EXPONENT_TO_VALUE(v)	((1<<v)-1)
+#define	ATH_TXOP_TO_US(v)		(v<<5)
+	struct ieee80211com *ic = &sc->sc_ic;
+	struct ath_txq *txq = sc->sc_ac2q[ac];
+	struct wmeParams *wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[ac];
+	struct ath_hal *ah = sc->sc_ah;
+	HAL_TXQ_INFO qi;
+
+	ath_hal_gettxqueueprops(ah, txq->axq_qnum, &qi);
+	qi.tqi_aifs = wmep->wmep_aifsn;
+	qi.tqi_cwmin = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmin);
+	qi.tqi_cwmax = ATH_EXPONENT_TO_VALUE(wmep->wmep_logcwmax);	
+	qi.tqi_burstTime = ATH_TXOP_TO_US(wmep->wmep_txopLimit);
+
+	if (!ath_hal_settxqueueprops(ah, txq->axq_qnum, &qi)) {
+		device_printf(sc->sc_dev, "unable to update hardware queue "
+			"parameters for %s traffic!\n",
+			ieee80211_wme_acnames[ac]);
+		return 0;
+	} else {
+		ath_hal_resettxqueue(ah, txq->axq_qnum); /* push to h/w */
+		return 1;
+	}
+#undef ATH_TXOP_TO_US
+#undef ATH_EXPONENT_TO_VALUE
+}
+
+/*
+ * Callback from the 802.11 layer to update WME parameters.
+ */
+static int 
+ath_wme_update(struct ieee80211com *ic)
+{
+	struct ath_softc *sc = ic->ic_ifp->if_softc;
+
+	return !ath_txq_update(sc, WME_AC_BE) ||
+	    !ath_txq_update(sc, WME_AC_BK) ||
+	    !ath_txq_update(sc, WME_AC_VI) ||
+	    !ath_txq_update(sc, WME_AC_VO) ? EIO : 0;
+}
+
+/*
  * Reclaim resources for a setup queue.
  */
 static void
@@ -2866,7 +2927,11 @@
 		else
 			txrate = an->an_tx_mgtrate;
 		/* NB: force all management frames to highest queue */
-		txq = sc->sc_ac2q[WME_AC_VO];
+		if (ni->ni_flags & IEEE80211_NODE_QOS) {
+			/* NB: force all management frames to highest queue */
+			txq = sc->sc_ac2q[WME_AC_VO];
+		} else
+			txq = sc->sc_ac2q[WME_AC_BE];
 		flags |= HAL_TXDESC_INTREQ;	/* force interrupt */
 		break;
 	case IEEE80211_FC0_TYPE_CTL:
@@ -2878,7 +2943,11 @@
 		else
 			txrate = an->an_tx_mgtrate;
 		/* NB: force all ctl frames to highest queue */
-		txq = sc->sc_ac2q[WME_AC_VO];
+		if (ni->ni_flags & IEEE80211_NODE_QOS) {
+			/* NB: force all ctl frames to highest queue */
+			txq = sc->sc_ac2q[WME_AC_VO];
+		} else
+			txq = sc->sc_ac2q[WME_AC_BE];
 		flags |= HAL_TXDESC_INTREQ;	/* force interrupt */
 		break;
 	case IEEE80211_FC0_TYPE_DATA:
@@ -2892,10 +2961,12 @@
 		 * Default all non-QoS traffic to the background queue.
 		 */
 		if (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS) {
-			/* XXX validate skb->priority */
-			txq = sc->sc_ac2q[M_WME_GETAC(m0)];
+			u_int pri = M_WME_GETAC(m0);
+			txq = sc->sc_ac2q[pri];
+			if (ic->ic_wme.wme_wmeChanParams.cap_wmeParams[pri].wmep_noackPolicy)
+				 flags |= HAL_TXDESC_NOACK;
 		} else
-			txq = sc->sc_ac2q[WME_AC_BK];
+			txq = sc->sc_ac2q[WME_AC_BE];
 		break;
 	default:
 		if_printf(ifp, "bogus frame type 0x%x (%s)\n",
@@ -3095,7 +3166,22 @@
 			__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 ?
+			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);
+	}
+#endif
 	/*
 	 * Insert the frame on the outbound list and
 	 * pass it on to the hardware.
@@ -3137,11 +3223,12 @@
 ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
 {
 	struct ath_hal *ah = sc->sc_ah;
+	struct ieee80211com *ic = &sc->sc_ic;
 	struct ath_buf *bf;
 	struct ath_desc *ds;
 	struct ieee80211_node *ni;
 	struct ath_node *an;
-	int sr, lr;
+	int sr, lr, pri;
 	HAL_STATUS status;
 
 	DPRINTF(sc, ATH_DEBUG_TX_PROC, "%s: tx queue %u head %p link %p\n",
@@ -3168,6 +3255,12 @@
 			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);
 
@@ -3182,6 +3275,9 @@
 					ds->ds_txstat.ts_rssi;
 				ATH_RSSI_LPF(an->an_halstats.ns_avgtxrssi,
 					ds->ds_txstat.ts_rssi);
+				pri = M_WME_GETAC(bf->bf_m);
+				if (pri >= WME_AC_VO)
+					ic->ic_wme.wme_hipri_traffic++;
 			} else {
 				if (ds->ds_txstat.ts_status & HAL_TXERR_XRETRY)
 					sc->sc_stats.ast_tx_xretries++;
@@ -4320,7 +4416,7 @@
 		for (i = 0; i <= WME_AC_VO; i++) {
 			struct ath_txq *txq = sc->sc_ac2q[i];
 			if_printf(ifp, "Use hw queue %u for %s traffic\n",
-				txq->axq_qnum, acnames[i]);
+				txq->axq_qnum, ieee80211_wme_acnames[i]);
 		}
 		if_printf(ifp, "Use hw queue %u for CAB traffic\n",
 			sc->sc_cabq->axq_qnum);

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

@@ -353,6 +353,10 @@
 	((*(_ah)->ah_resetTxQueue)((_ah), (_q)))
 #define	ath_hal_releasetxqueue(_ah, _q) \
 	((*(_ah)->ah_releaseTxQueue)((_ah), (_q)))
+#define	ath_hal_gettxqueueprops(_ah, _q, _qi) \
+	((*(_ah)->ah_getTxQueueProps)((_ah), (_q), (_qi)))
+#define	ath_hal_settxqueueprops(_ah, _q, _qi) \
+	((*(_ah)->ah_setTxQueueProps)((_ah), (_q), (_qi)))
 #define	ath_hal_getrfgain(_ah) \
 	((*(_ah)->ah_getRfGain)((_ah)))
 #define	ath_hal_getdefantenna(_ah) \
@@ -421,6 +425,8 @@
 	(ath_hal_getcapability(_ah, HAL_CAP_TPC, 1, NULL) == HAL_OK)
 #define	ath_hal_settpc(_ah, _v) \
 	ath_hal_setcapability(_ah, HAL_CAP_TPC, 1, _v, NULL)
+#define	ath_hal_hasbursting(_ah) \
+	(ath_hal_getcapability(_ah, HAL_CAP_BURST, 0, NULL) == HAL_OK)
 
 #define	ath_hal_setuprxdesc(_ah, _ds, _size, _intreq) \
 	((*(_ah)->ah_setupRxDesc)((_ah), (_ds), (_size), (_intreq)))
@@ -440,6 +446,10 @@
 	((*(_ah)->ah_fillTxDesc)((_ah), (_ds), (_l), (_first), (_last), (_ds0)))
 #define	ath_hal_txprocdesc(_ah, _ds) \
 	((*(_ah)->ah_procTxDesc)((_ah), (_ds)))
+#define	ath_hal_updateCTSForBursting(_ah, _ds, _prevds, _prevdsWithCTS, \
+		_gatingds,  _txOpLimit, _ctsDuration) \
+	((*(_ah)->ah_updateCTSForBursting)((_ah), (_ds), (_prevds), \
+		(_prevdsWithCTS), (_gatingds), (_txOpLimit), (_ctsDuration)))
 
 #define ath_hal_gpioCfgOutput(_ah, _gpio) \
         ((*(_ah)->ah_gpioCfgOutput)((_ah), (_gpio)))


More information about the p4-projects mailing list