Date: Tue, 23 Nov 2004 03:54:53 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 65687 for review Message-ID: <200411230354.iAN3srcx002390@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=65687 Change 65687 by sam@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)))
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200411230354.iAN3srcx002390>