Date: Wed, 30 Mar 2005 05:20:06 GMT From: Sam Leffler <sam@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 74079 for review Message-ID: <200503300520.j2U5K6BQ004840@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=74079 Change 74079 by sam@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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200503300520.j2U5K6BQ004840>
