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