summaryrefslogtreecommitdiff
path: root/sys/dev/ic/rt2661.c
diff options
context:
space:
mode:
authorDamien Bergamini <damien@cvs.openbsd.org>2006-06-14 19:31:48 +0000
committerDamien Bergamini <damien@cvs.openbsd.org>2006-06-14 19:31:48 +0000
commit847bf49bad264b13a0af4189e5a09ab523bd15fb (patch)
treec4fe4b3799898a823db91920ef09966505b41c6b /sys/dev/ic/rt2661.c
parent703a01ef40649180abe647d36fb34abffe0ed912 (diff)
must use RTS/CTS protection when sending frames at OFDM rates in a BSS
with non-ERP STAs. some bits are missing in net80211 though, so this code won't be triggered yet.
Diffstat (limited to 'sys/dev/ic/rt2661.c')
-rw-r--r--sys/dev/ic/rt2661.c57
1 files changed, 31 insertions, 26 deletions
diff --git a/sys/dev/ic/rt2661.c b/sys/dev/ic/rt2661.c
index fcbf4e06c2c..f9cce6bfd30 100644
--- a/sys/dev/ic/rt2661.c
+++ b/sys/dev/ic/rt2661.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rt2661.c,v 1.20 2006/06/10 20:31:59 damien Exp $ */
+/* $OpenBSD: rt2661.c,v 1.21 2006/06/14 19:31:47 damien Exp $ */
/*-
* Copyright (c) 2006
@@ -183,9 +183,6 @@ static const struct {
RT2661_DEF_BBP
};
-/*
- * Default settings for RF registers; values taken from the reference driver.
- */
static const struct rfprog {
uint8_t chan;
uint32_t r1, r2, r3, r4;
@@ -1118,9 +1115,8 @@ rt2661_rx_intr(struct rt2661_softc *sc)
htole64(((uint64_t)tsf_hi << 32) | tsf_lo);
tap->wr_flags = 0;
tap->wr_rate = rt2661_rxrate(desc);
- tap->wr_chan_freq = htole16(ic->ic_ibss_chan->ic_freq);
- tap->wr_chan_flags =
- htole16(ic->ic_ibss_chan->ic_flags);
+ tap->wr_chan_freq = htole16(sc->sc_curchan->ic_freq);
+ tap->wr_chan_flags = htole16(sc->sc_curchan->ic_flags);
tap->wr_antsignal = desc->rssi;
M_DUP_PKTHDR(&mb, m);
@@ -1172,7 +1168,6 @@ skip: desc->flags |= htole32(RT2661_RX_BUSY);
rt2661_start(ifp);
}
-/* ARGSUSED */
void
rt2661_mcu_beacon_expire(struct rt2661_softc *sc)
{
@@ -1490,8 +1485,8 @@ rt2661_tx_mgt(struct rt2661_softc *sc, struct mbuf *m0,
tap->wt_flags = 0;
tap->wt_rate = rate;
- tap->wt_chan_freq = htole16(ic->ic_ibss_chan->ic_freq);
- tap->wt_chan_flags = htole16(ic->ic_ibss_chan->ic_flags);
+ tap->wt_chan_freq = htole16(sc->sc_curchan->ic_freq);
+ tap->wt_chan_flags = htole16(sc->sc_curchan->ic_flags);
M_DUP_PKTHDR(&mb, m0);
mb.m_data = (caddr_t)tap;
@@ -1512,7 +1507,7 @@ rt2661_tx_mgt(struct rt2661_softc *sc, struct mbuf *m0,
RAL_SIFS;
*(uint16_t *)wh->i_dur = htole16(dur);
- /* tell hardware to add timestamp in probe responses */
+ /* tell hardware to set timestamp in probe responses */
if ((wh->i_fc[0] &
(IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
(IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
@@ -1587,7 +1582,7 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0,
struct mbuf *mnew;
uint16_t dur;
uint32_t flags = 0;
- int rate, error;
+ int rate, useprot, error;
wh = mtod(m0, struct ieee80211_frame *);
@@ -1619,13 +1614,19 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0,
wh = mtod(m0, struct ieee80211_frame *);
}
- /*
+ /*-
* IEEE Std 802.11-1999, pp 82: "A STA shall use an RTS/CTS exchange
* for directed frames only when the length of the MPDU is greater
- * than the length threshold indicated by [...]" ic_rtsthreshold.
+ * than the length threshold indicated by" ic_rtsthreshold.
+ *
+ * IEEE Std 802.11-2003g, pp 13: "ERP STAs shall use protection
+ * mechanism (such as RTS/CTS or CTS-to-self) for ERP-OFDM MPDUs of
+ * type Data or an MMPDU".
*/
- if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
- m0->m_pkthdr.len + IEEE80211_CRC_LEN > ic->ic_rtsthreshold) {
+ useprot = !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
+ (m0->m_pkthdr.len + IEEE80211_CRC_LEN > ic->ic_rtsthreshold ||
+ ((ic->ic_flags & IEEE80211_F_USEPROT) && RAL_RATE_IS_OFDM(rate)));
+ if (useprot) {
struct mbuf *m;
uint16_t dur;
int rtsrate, ackrate;
@@ -1639,6 +1640,12 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0,
3 * RAL_SIFS;
m = rt2661_get_rts(sc, wh, dur);
+ if (m == NULL) {
+ printf("%s: could not allocate RTS frame\n",
+ sc->sc_dev.dv_xname);
+ m_freem(m0);
+ return ENOBUFS;
+ }
desc = &txq->desc[txq->cur];
data = &txq->data[txq->cur];
@@ -1676,11 +1683,11 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0,
txq->cur = (txq->cur + 1) % RT2661_TX_RING_COUNT;
/*
- * IEEE Std 802.11-1999: when an RTS/CTS exchange is used, the
+ * IEEE Std 802.11-1999: "when an RTS/CTS exchange is used, the
* asynchronous data frame shall be transmitted after the CTS
- * frame and a SIFS period.
+ * frame and a SIFS period".
*/
- flags |= RT2661_TX_LONG_RETRY | RT2661_TX_IFS;
+ flags |= RT2661_TX_LONG_RETRY | RT2661_TX_IFS_SIFS;
}
data = &txq->data[txq->cur];
@@ -1738,8 +1745,8 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0,
tap->wt_flags = 0;
tap->wt_rate = rate;
- tap->wt_chan_freq = htole16(ic->ic_ibss_chan->ic_freq);
- tap->wt_chan_flags = htole16(ic->ic_ibss_chan->ic_flags);
+ tap->wt_chan_freq = htole16(sc->sc_curchan->ic_freq);
+ tap->wt_chan_flags = htole16(sc->sc_curchan->ic_flags);
M_DUP_PKTHDR(&mb, m0);
mb.m_data = (caddr_t)tap;
@@ -1817,8 +1824,7 @@ rt2661_start(struct ifnet *ifp)
m0->m_pkthdr.rcvif = NULL;
#if NBPFILTER > 0
if (ic->ic_rawbpf != NULL)
- bpf_mtap(ic->ic_rawbpf, m0,
- BPF_DIRECTION_OUT);
+ bpf_mtap(ic->ic_rawbpf, m0, BPF_DIRECTION_OUT);
#endif
if (rt2661_tx_mgt(sc, m0, ni) != 0)
break;
@@ -2912,7 +2918,7 @@ rt2661_power(int why, void *arg)
int s;
DPRINTF(("%s: rt2661_power(%d)\n", sc->sc_dev.dv_xname, why));
-
+
s = splnet();
switch (why) {
case PWR_SUSPEND:
@@ -2940,7 +2946,6 @@ rt2661_shutdown(void *arg)
{
struct rt2661_softc *sc = arg;
struct ifnet *ifp = &sc->sc_ic.ic_if;
-
+
rt2661_stop(ifp, 1);
}
-