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