diff options
author | Damien Bergamini <damien@cvs.openbsd.org> | 2006-11-13 20:06:39 +0000 |
---|---|---|
committer | Damien Bergamini <damien@cvs.openbsd.org> | 2006-11-13 20:06:39 +0000 |
commit | f815983418862c69f38d2ade274a4785797e276c (patch) | |
tree | e83e63c3ae3875de702975496c3bd10651422e08 /sys/dev | |
parent | 5dfdad8c9a03b5917a916a713c679847e5ca3fbb (diff) |
first round of commits for proper 11b/g protection support:
- use the newly introduced ieee80211_get_rts() and
ieee80211_get_cts_to_self() functions.
- use CTS-to-self instead of RTS/CTS to protect OFDM frames in
a mixed 11b/g BSS.
- make sure multicast frames are sent using CCK modulation.
remove support for 5GHz radios in ral(4) RT2560 and ural(4).
i'm not aware of any such adapters on the market and 11a code
is known to be broken.
some cleanup while i'm here.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/ic/rt2560.c | 298 | ||||
-rw-r--r-- | sys/dev/ic/rt2560reg.h | 49 | ||||
-rw-r--r-- | sys/dev/ic/rt2661.c | 185 | ||||
-rw-r--r-- | sys/dev/pci/if_wpi.c | 41 | ||||
-rw-r--r-- | sys/dev/pci/if_wpireg.h | 3 | ||||
-rw-r--r-- | sys/dev/usb/if_ral.c | 265 | ||||
-rw-r--r-- | sys/dev/usb/if_ralreg.h | 50 | ||||
-rw-r--r-- | sys/dev/usb/if_ralvar.h | 10 | ||||
-rw-r--r-- | sys/dev/usb/if_rum.c | 207 | ||||
-rw-r--r-- | sys/dev/usb/if_rumreg.h | 4 | ||||
-rw-r--r-- | sys/dev/usb/if_rumvar.h | 16 | ||||
-rw-r--r-- | sys/dev/usb/if_zyd.c | 41 |
12 files changed, 511 insertions, 658 deletions
diff --git a/sys/dev/ic/rt2560.c b/sys/dev/ic/rt2560.c index e2b0c8138ca..714d1621e16 100644 --- a/sys/dev/ic/rt2560.c +++ b/sys/dev/ic/rt2560.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rt2560.c,v 1.24 2006/10/22 12:14:44 damien Exp $ */ +/* $OpenBSD: rt2560.c,v 1.25 2006/11/13 20:06:38 damien Exp $ */ /*- * Copyright (c) 2005, 2006 @@ -105,7 +105,7 @@ void rt2560_rx_intr(struct rt2560_softc *); void rt2560_beacon_expire(struct rt2560_softc *); void rt2560_wakeup_expire(struct rt2560_softc *); #if NBPFILTER > 0 -uint8_t rt2560_rxrate(struct rt2560_rx_desc *); +uint8_t rt2560_rxrate(const struct rt2560_rx_desc *); #endif int rt2560_ack_rate(struct ieee80211com *, int); uint16_t rt2560_txtime(int, int, uint32_t); @@ -117,8 +117,6 @@ int rt2560_tx_bcn(struct rt2560_softc *, struct mbuf *, struct ieee80211_node *); int rt2560_tx_mgt(struct rt2560_softc *, struct mbuf *, struct ieee80211_node *); -struct mbuf *rt2560_get_rts(struct rt2560_softc *, - struct ieee80211_frame *, uint16_t); int rt2560_tx_data(struct rt2560_softc *, struct mbuf *, struct ieee80211_node *); void rt2560_start(struct ifnet *); @@ -150,11 +148,8 @@ void rt2560_stop(struct ifnet *, int); void rt2560_power(int, void *); /* - * Supported rates for 802.11a/b/g modes (in 500Kbps unit). + * Supported rates for 802.11b/g modes (in 500Kbps unit). */ -static const struct ieee80211_rateset rt2560_rateset_11a = - { 8, { 12, 18, 24, 36, 48, 72, 96, 108 } }; - static const struct ieee80211_rateset rt2560_rateset_11b = { 4, { 2, 4, 11, 22 } }; @@ -184,13 +179,6 @@ static const uint32_t rt2560_rf2525e_r2[] = RT2560_RF2525E_R2; static const uint32_t rt2560_rf2526_r2[] = RT2560_RF2526_R2; static const uint32_t rt2560_rf2526_hi_r2[] = RT2560_RF2526_HI_R2; -static const struct { - uint8_t chan; - uint32_t r1, r2, r4; -} rt2560_rf5222[] = { - RT2560_RF5222 -}; - int rt2560_attach(void *xsc, int id) { @@ -226,28 +214,24 @@ rt2560_attach(void *xsc, int id) sc->sc_dev.dv_xname); goto fail1; } - error = rt2560_alloc_tx_ring(sc, &sc->atimq, RT2560_ATIM_RING_COUNT); if (error != 0) { printf("%s: could not allocate ATIM ring\n", sc->sc_dev.dv_xname); goto fail2; } - error = rt2560_alloc_tx_ring(sc, &sc->prioq, RT2560_PRIO_RING_COUNT); if (error != 0) { printf("%s: could not allocate Prio ring\n", sc->sc_dev.dv_xname); goto fail3; } - error = rt2560_alloc_tx_ring(sc, &sc->bcnq, RT2560_BEACON_RING_COUNT); if (error != 0) { printf("%s: could not allocate Beacon ring\n", sc->sc_dev.dv_xname); goto fail4; } - error = rt2560_alloc_rx_ring(sc, &sc->rxq, RT2560_RX_RING_COUNT); if (error != 0) { printf("%s: could not allocate Rx ring\n", @@ -269,28 +253,6 @@ rt2560_attach(void *xsc, int id) IEEE80211_C_SHSLOT | /* short slot time supported */ IEEE80211_C_WEP; /* s/w WEP */ - if (sc->rf_rev == RT2560_RF_5222) { - /* set supported .11a rates */ - ic->ic_sup_rates[IEEE80211_MODE_11A] = rt2560_rateset_11a; - - /* set supported .11a channels */ - for (i = 36; i <= 64; i += 4) { - ic->ic_channels[i].ic_freq = - ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ); - ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A; - } - for (i = 100; i <= 140; i += 4) { - ic->ic_channels[i].ic_freq = - ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ); - ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A; - } - for (i = 149; i <= 161; i += 4) { - ic->ic_channels[i].ic_freq = - ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ); - ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A; - } - } - /* set supported .11b and .11g rates */ ic->ic_sup_rates[IEEE80211_MODE_11B] = rt2560_rateset_11b; ic->ic_sup_rates[IEEE80211_MODE_11G] = rt2560_rateset_11g; @@ -345,7 +307,6 @@ rt2560_attach(void *xsc, int id) printf("%s: WARNING: unable to establish shutdown hook\n", sc->sc_dev.dv_xname); } - sc->sc_powerhook = powerhook_establish(rt2560_power, sc); if (sc->sc_powerhook == NULL) { printf("%s: WARNING: unable to establish power hook\n", @@ -463,13 +424,11 @@ fail: rt2560_free_tx_ring(sc, ring); void rt2560_reset_tx_ring(struct rt2560_softc *sc, struct rt2560_tx_ring *ring) { - struct rt2560_tx_desc *desc; - struct rt2560_tx_data *data; int i; for (i = 0; i < ring->count; i++) { - desc = &ring->desc[i]; - data = &ring->data[i]; + struct rt2560_tx_desc *desc = &ring->desc[i]; + struct rt2560_tx_data *data = &ring->data[i]; if (data->m != NULL) { bus_dmamap_sync(sc->sc_dmat, data->map, 0, @@ -499,7 +458,6 @@ rt2560_reset_tx_ring(struct rt2560_softc *sc, struct rt2560_tx_ring *ring) void rt2560_free_tx_ring(struct rt2560_softc *sc, struct rt2560_tx_ring *ring) { - struct rt2560_tx_data *data; int i; if (ring->desc != NULL) { @@ -513,7 +471,7 @@ rt2560_free_tx_ring(struct rt2560_softc *sc, struct rt2560_tx_ring *ring) if (ring->data != NULL) { for (i = 0; i < ring->count; i++) { - data = &ring->data[i]; + struct rt2560_tx_data *data = &ring->data[i]; if (data->m != NULL) { bus_dmamap_sync(sc->sc_dmat, data->map, 0, @@ -540,8 +498,6 @@ int rt2560_alloc_rx_ring(struct rt2560_softc *sc, struct rt2560_rx_ring *ring, int count) { - struct rt2560_rx_desc *desc; - struct rt2560_rx_data *data; int i, nsegs, error; ring->count = count; @@ -598,8 +554,8 @@ rt2560_alloc_rx_ring(struct rt2560_softc *sc, struct rt2560_rx_ring *ring, */ memset(ring->data, 0, count * sizeof (struct rt2560_rx_data)); for (i = 0; i < count; i++) { - desc = &sc->rxq.desc[i]; - data = &sc->rxq.data[i]; + struct rt2560_rx_desc *desc = &sc->rxq.desc[i]; + struct rt2560_rx_data *data = &sc->rxq.data[i]; error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0, BUS_DMA_NOWAIT, &data->map); @@ -616,7 +572,6 @@ rt2560_alloc_rx_ring(struct rt2560_softc *sc, struct rt2560_rx_ring *ring, error = ENOMEM; goto fail; } - MCLGET(data->m, M_DONTWAIT); if (!(data->m->m_flags & M_EXT)) { printf("%s: could not allocate rx mbuf cluster\n", @@ -666,7 +621,6 @@ rt2560_reset_rx_ring(struct rt2560_softc *sc, struct rt2560_rx_ring *ring) void rt2560_free_rx_ring(struct rt2560_softc *sc, struct rt2560_rx_ring *ring) { - struct rt2560_rx_data *data; int i; if (ring->desc != NULL) { @@ -680,7 +634,7 @@ rt2560_free_rx_ring(struct rt2560_softc *sc, struct rt2560_rx_ring *ring) if (ring->data != NULL) { for (i = 0; i < ring->count; i++) { - data = &ring->data[i]; + struct rt2560_rx_data *data = &ring->data[i]; if (data->m != NULL) { bus_dmamap_sync(sc->sc_dmat, data->map, 0, @@ -796,11 +750,10 @@ rt2560_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) ostate = ic->ic_state; timeout_del(&sc->scan_to); + timeout_del(&sc->amrr_to); switch (nstate) { case IEEE80211_S_INIT: - timeout_del(&sc->amrr_to); - if (ostate == IEEE80211_S_RUN) { /* abort TSF synchronization */ RAL_WRITE(sc, RT2560_CSR14, 0); @@ -936,7 +889,6 @@ rt2560_eeprom_read(struct rt2560_softc *sc, uint8_t addr) void rt2560_encryption_intr(struct rt2560_softc *sc) { - struct rt2560_tx_desc *desc; int hw; /* retrieve last descriptor index processed by cipher engine */ @@ -944,7 +896,8 @@ rt2560_encryption_intr(struct rt2560_softc *sc) RT2560_TX_DESC_SIZE; for (; sc->txq.next_encrypt != hw;) { - desc = &sc->txq.desc[sc->txq.next_encrypt]; + struct rt2560_tx_desc *desc = + &sc->txq.desc[sc->txq.next_encrypt]; bus_dmamap_sync(sc->sc_dmat, sc->txq.map, sc->txq.next_encrypt * RT2560_TX_DESC_SIZE, @@ -982,13 +935,11 @@ rt2560_tx_intr(struct rt2560_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = &ic->ic_if; - struct rt2560_tx_desc *desc; - struct rt2560_tx_data *data; - struct rt2560_node *rn; for (;;) { - desc = &sc->txq.desc[sc->txq.next]; - data = &sc->txq.data[sc->txq.next]; + struct rt2560_tx_desc *desc = &sc->txq.desc[sc->txq.next]; + struct rt2560_tx_data *data = &sc->txq.data[sc->txq.next]; + struct rt2560_node *rn; bus_dmamap_sync(sc->sc_dmat, sc->txq.map, sc->txq.next * RT2560_TX_DESC_SIZE, RT2560_TX_DESC_SIZE, @@ -1063,12 +1014,10 @@ rt2560_prio_intr(struct rt2560_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = &ic->ic_if; - struct rt2560_tx_desc *desc; - struct rt2560_tx_data *data; for (;;) { - desc = &sc->prioq.desc[sc->prioq.next]; - data = &sc->prioq.data[sc->prioq.next]; + struct rt2560_tx_desc *desc = &sc->prioq.desc[sc->prioq.next]; + struct rt2560_tx_data *data = &sc->prioq.data[sc->prioq.next]; bus_dmamap_sync(sc->sc_dmat, sc->prioq.map, sc->prioq.next * RT2560_TX_DESC_SIZE, RT2560_TX_DESC_SIZE, @@ -1135,8 +1084,6 @@ rt2560_decryption_intr(struct rt2560_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = &ic->ic_if; - struct rt2560_rx_desc *desc; - struct rt2560_rx_data *data; struct ieee80211_frame *wh; struct ieee80211_node *ni; struct mbuf *mnew, *m; @@ -1147,8 +1094,10 @@ rt2560_decryption_intr(struct rt2560_softc *sc) RT2560_RX_DESC_SIZE; for (; sc->rxq.cur_decrypt != hw;) { - desc = &sc->rxq.desc[sc->rxq.cur_decrypt]; - data = &sc->rxq.data[sc->rxq.cur_decrypt]; + struct rt2560_rx_desc *desc = + &sc->rxq.desc[sc->rxq.cur_decrypt]; + struct rt2560_rx_data *data = + &sc->rxq.data[sc->rxq.cur_decrypt]; bus_dmamap_sync(sc->sc_dmat, sc->rxq.map, sc->rxq.cur_decrypt * RT2560_TX_DESC_SIZE, @@ -1181,7 +1130,6 @@ rt2560_decryption_intr(struct rt2560_softc *sc) ifp->if_ierrors++; goto skip; } - MCLGET(mnew, M_DONTWAIT); if (!(mnew->m_flags & M_EXT)) { m_freem(mnew); @@ -1288,12 +1236,9 @@ skip: desc->flags = htole32(RT2560_RX_BUSY); void rt2560_rx_intr(struct rt2560_softc *sc) { - struct rt2560_rx_desc *desc; - struct rt2560_rx_data *data; - for (;;) { - desc = &sc->rxq.desc[sc->rxq.cur]; - data = &sc->rxq.data[sc->rxq.cur]; + struct rt2560_rx_desc *desc = &sc->rxq.desc[sc->rxq.cur]; + struct rt2560_rx_data *data = &sc->rxq.data[sc->rxq.cur]; bus_dmamap_sync(sc->sc_dmat, sc->rxq.map, sc->rxq.cur * RT2560_RX_DESC_SIZE, RT2560_RX_DESC_SIZE, @@ -1445,7 +1390,7 @@ rt2560_intr(void *arg) */ #if NBPFILTER > 0 uint8_t -rt2560_rxrate(struct rt2560_rx_desc *desc) +rt2560_rxrate(const struct rt2560_rx_desc *desc) { if (letoh32(desc->flags) & RT2560_RX_OFDM) { /* reverse function of rt2560_plcp_signal */ @@ -1475,7 +1420,6 @@ rt2560_rxrate(struct rt2560_rx_desc *desc) /* * Return the expected ack rate for a frame transmitted at rate `rate'. - * XXX: this should depend on the destination node basic rate set. */ int rt2560_ack_rate(struct ieee80211com *ic, int rate) @@ -1609,13 +1553,11 @@ rt2560_tx_bcn(struct rt2560_softc *sc, struct mbuf *m0, struct ieee80211com *ic = &sc->sc_ic; struct rt2560_tx_desc *desc; struct rt2560_tx_data *data; - int rate, error; + int rate = 2, error; desc = &sc->bcnq.desc[sc->bcnq.cur]; data = &sc->bcnq.data[sc->bcnq.cur]; - rate = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? 12 : 2; - error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m0, BUS_DMA_NOWAIT); if (error != 0) { @@ -1669,13 +1611,11 @@ rt2560_tx_mgt(struct rt2560_softc *sc, struct mbuf *m0, struct ieee80211_frame *wh; uint16_t dur; uint32_t flags = 0; - int rate, error; + int rate = 2, error; desc = &sc->prioq.desc[sc->prioq.cur]; data = &sc->prioq.data[sc->prioq.cur]; - rate = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? 12 : 2; - wh = mtod(m0, struct ieee80211_frame *); if (wh->i_fc[1] & IEEE80211_FC1_WEP) { @@ -1722,7 +1662,7 @@ rt2560_tx_mgt(struct rt2560_softc *sc, struct mbuf *m0, wh = mtod(m0, struct ieee80211_frame *); if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { - flags |= RT2560_TX_ACK; + flags |= RT2560_TX_NEED_ACK; dur = rt2560_txtime(RAL_ACK_SIZE, rate, ic->ic_flags) + RAL_SIFS; @@ -1755,61 +1695,23 @@ rt2560_tx_mgt(struct rt2560_softc *sc, struct mbuf *m0, return 0; } -/* - * Build a RTS control frame. - */ -struct mbuf * -rt2560_get_rts(struct rt2560_softc *sc, struct ieee80211_frame *wh, - uint16_t dur) -{ - struct ieee80211_frame_rts *rts; - struct mbuf *m; - - MGETHDR(m, M_DONTWAIT, MT_DATA); - if (m == NULL) { - sc->sc_ic.ic_stats.is_tx_nombuf++; - printf("%s: could not allocate RTS frame\n", - sc->sc_dev.dv_xname); - return NULL; - } - - rts = mtod(m, struct ieee80211_frame_rts *); - - rts->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_CTL | - IEEE80211_FC0_SUBTYPE_RTS; - rts->i_fc[1] = IEEE80211_FC1_DIR_NODS; - *(uint16_t *)rts->i_dur = htole16(dur); - IEEE80211_ADDR_COPY(rts->i_ra, wh->i_addr1); - IEEE80211_ADDR_COPY(rts->i_ta, wh->i_addr2); - - m->m_pkthdr.len = m->m_len = sizeof (struct ieee80211_frame_rts); - - return m; -} - int rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) { struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = &ic->ic_if; + struct rt2560_tx_ring *txq = &sc->txq; struct rt2560_tx_desc *desc; struct rt2560_tx_data *data; struct ieee80211_frame *wh; struct mbuf *mnew; uint16_t dur; uint32_t flags = 0; - int rate, useprot, error; + int pktlen, rate, needcts = 0, needrts = 0, error; wh = mtod(m0, struct ieee80211_frame *); - if (ic->ic_fixed_rate != -1) { - rate = ic->ic_sup_rates[ic->ic_curmode]. - rs_rates[ic->ic_fixed_rate]; - } else - rate = ni->ni_rates.rs_rates[ni->ni_txrate]; - rate &= IEEE80211_RATE_VAL; - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { m0 = ieee80211_wep_crypt(ifp, m0, 1); if (m0 == NULL) @@ -1819,6 +1721,22 @@ rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0, wh = mtod(m0, struct ieee80211_frame *); } + /* compute actual packet length (including CRC and crypto overhead) */ + pktlen = m0->m_pkthdr.len + IEEE80211_CRC_LEN; + + /* pickup a rate */ + if (IEEE80211_IS_MULTICAST(wh->i_addr1) || + ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == + IEEE80211_FC0_TYPE_MGT)) { + /* mgmt/multicast frames are sent at the lowest avail. rate */ + rate = ni->ni_rates.rs_rates[0]; + } else if (ic->ic_fixed_rate != -1) { + rate = ic->ic_sup_rates[ic->ic_curmode]. + rs_rates[ic->ic_fixed_rate]; + } else + rate = ni->ni_rates.rs_rates[ni->ni_txrate]; + rate &= IEEE80211_RATE_VAL; + /* * Packet Bursting: backoff after ppb=8 frames to give other STAs a * chance to contend for the wireless medium. @@ -1826,77 +1744,83 @@ rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0, if (ic->ic_opmode == IEEE80211_M_STA && (ni->ni_txseq & 7)) flags |= RT2560_TX_IFS_SIFS; - /*- - * 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. - * - * 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". - */ - 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; + /* check if RTS/CTS or CTS-to-self protection must be used */ + if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { + /* multicast frames are not sent at OFDM rates in 802.11b/g */ + if (pktlen > ic->ic_rtsthreshold) { + needrts = 1; /* RTS/CTS based on frame length */ + } else if ((ic->ic_flags & IEEE80211_F_USEPROT) && + RAL_RATE_IS_OFDM(rate)) { + if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) + needcts = 1; /* CTS-to-self */ + else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) + needrts = 1; /* RTS/CTS */ + } + } + if (needrts || needcts) { + struct mbuf *mprot; + int protrate, ackrate; uint16_t dur; - int rtsrate, ackrate; - rtsrate = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? 12 : 2; - ackrate = rt2560_ack_rate(ic, rate); + protrate = 2; /* XXX */ + ackrate = rt2560_ack_rate(ic, rate); - dur = rt2560_txtime(m0->m_pkthdr.len + 4, rate, ic->ic_flags) + - rt2560_txtime(RAL_CTS_SIZE, rtsrate, ic->ic_flags) + + dur = rt2560_txtime(pktlen, rate, ic->ic_flags) + rt2560_txtime(RAL_ACK_SIZE, ackrate, ic->ic_flags) + - 3 * RAL_SIFS; - - m = rt2560_get_rts(sc, wh, dur); - if (m == NULL) { - printf("%s: could not allocate RTS frame\n", + 2 * RAL_SIFS; + if (needrts) { + dur += rt2560_txtime(RAL_CTS_SIZE, rt2560_ack_rate(ic, + protrate), ic->ic_flags) + RAL_SIFS; + mprot = ieee80211_get_rts(ic, wh, dur); + } else { + mprot = ieee80211_get_cts_to_self(ic, dur); + } + if (mprot == NULL) { + printf("%s: could not allocate protection frame\n", sc->sc_dev.dv_xname); m_freem(m0); return ENOBUFS; } - desc = &sc->txq.desc[sc->txq.cur_encrypt]; - data = &sc->txq.data[sc->txq.cur_encrypt]; + desc = &txq->desc[txq->cur_encrypt]; + data = &txq->data[txq->cur_encrypt]; - error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m, + error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, mprot, BUS_DMA_NOWAIT); if (error != 0) { printf("%s: could not map mbuf (error %d)\n", sc->sc_dev.dv_xname, error); - m_freem(m); + m_freem(mprot); m_freem(m0); return error; } + data->m = mprot; /* avoid multiple free() of the same node for each fragment */ - ieee80211_ref_node(ni); + data->ni = ieee80211_ref_node(ni); - data->m = m; - data->ni = ni; + /* XXX may want to pass the protection frame to BPF */ - rt2560_setup_tx_desc(sc, desc, RT2560_TX_ACK | - RT2560_TX_MORE_FRAG, m->m_pkthdr.len, rtsrate, 1, + rt2560_setup_tx_desc(sc, desc, + (needrts ? RT2560_TX_NEED_ACK : 0) | RT2560_TX_MORE_FRAG, + mprot->m_pkthdr.len, protrate, 1, data->map->dm_segs->ds_addr); bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize, BUS_DMASYNC_PREWRITE); - bus_dmamap_sync(sc->sc_dmat, sc->txq.map, - sc->txq.cur_encrypt * RT2560_TX_DESC_SIZE, + bus_dmamap_sync(sc->sc_dmat, txq->map, + txq->cur_encrypt * RT2560_TX_DESC_SIZE, RT2560_TX_DESC_SIZE, BUS_DMASYNC_PREWRITE); - sc->txq.queued++; - sc->txq.cur_encrypt = - (sc->txq.cur_encrypt + 1) % RT2560_TX_RING_COUNT; + txq->queued++; + if (++txq->cur_encrypt >= txq->count) + txq->cur_encrypt = 0; flags |= RT2560_TX_LONG_RETRY | RT2560_TX_IFS_SIFS; } - data = &sc->txq.data[sc->txq.cur_encrypt]; - desc = &sc->txq.desc[sc->txq.cur_encrypt]; + data = &txq->data[txq->cur_encrypt]; + desc = &txq->desc[txq->cur_encrypt]; error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m0, BUS_DMA_NOWAIT); @@ -1914,7 +1838,6 @@ rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0, m_freem(m0); return ENOMEM; } - M_DUP_PKTHDR(mnew, m0); if (m0->m_pkthdr.len > MHLEN) { MCLGET(mnew, M_DONTWAIT); @@ -1967,7 +1890,7 @@ rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0, data->ni = ni; if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { - flags |= RT2560_TX_ACK; + flags |= RT2560_TX_NEED_ACK; dur = rt2560_txtime(RAL_ACK_SIZE, rt2560_ack_rate(ic, rate), ic->ic_flags) + RAL_SIFS; @@ -1979,16 +1902,17 @@ rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0, bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize, BUS_DMASYNC_PREWRITE); - bus_dmamap_sync(sc->sc_dmat, sc->txq.map, - sc->txq.cur_encrypt * RT2560_TX_DESC_SIZE, RT2560_TX_DESC_SIZE, + bus_dmamap_sync(sc->sc_dmat, txq->map, + txq->cur_encrypt * RT2560_TX_DESC_SIZE, RT2560_TX_DESC_SIZE, BUS_DMASYNC_PREWRITE); - DPRINTFN(10, ("sending data frame len=%u idx=%u rate=%u\n", - m0->m_pkthdr.len, sc->txq.cur_encrypt, rate)); + DPRINTFN(10, ("sending frame len=%u idx=%u rate=%u\n", + m0->m_pkthdr.len, txq->cur_encrypt, rate)); /* kick encrypt */ - sc->txq.queued++; - sc->txq.cur_encrypt = (sc->txq.cur_encrypt + 1) % RT2560_TX_RING_COUNT; + txq->queued++; + if (++txq->cur_encrypt >= txq->count) + txq->cur_encrypt = 0; RAL_WRITE(sc, RT2560_SECCSR1, RT2560_KICK_ENCRYPT); return 0; @@ -2228,16 +2152,13 @@ rt2560_set_chan(struct rt2560_softc *sc, struct ieee80211_channel *c) { struct ieee80211com *ic = &sc->sc_ic; uint8_t power, tmp; - u_int i, chan; + u_int chan; chan = ieee80211_chan2ieee(ic, c); if (chan == 0 || chan == IEEE80211_CHAN_ANY) return; - if (IEEE80211_IS_CHAN_2GHZ(c)) - power = min(sc->txpow[chan - 1], 31); - else - power = 31; + power = min(sc->txpow[chan - 1], 31); DPRINTFN(2, ("setting channel to %u, txpower to %u\n", chan, power)); @@ -2297,16 +2218,6 @@ rt2560_set_chan(struct rt2560_softc *sc, struct ieee80211_channel *c) rt2560_rf_write(sc, RT2560_RF4, (chan & 1) ? 0x00386 : 0x00381); break; - - /* dual-band RF */ - case RT2560_RF_5222: - for (i = 0; rt2560_rf5222[i].chan != chan; i++); - - rt2560_rf_write(sc, RT2560_RF1, rt2560_rf5222[i].r1); - rt2560_rf_write(sc, RT2560_RF2, rt2560_rf5222[i].r2); - rt2560_rf_write(sc, RT2560_RF3, power << 7 | 0x00040); - rt2560_rf_write(sc, RT2560_RF4, rt2560_rf5222[i].r4); - break; } if (ic->ic_opmode != IEEE80211_M_MONITOR && @@ -2465,12 +2376,9 @@ rt2560_set_basicrates(struct rt2560_softc *sc) if (ic->ic_curmode == IEEE80211_MODE_11B) { /* 11b basic rates: 1, 2Mbps */ RAL_WRITE(sc, RT2560_ARSP_PLCP_1, 0x3); - } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_bss->ni_chan)) { - /* 11a basic rates: 6, 12, 24Mbps */ - RAL_WRITE(sc, RT2560_ARSP_PLCP_1, 0x150); } else { - /* 11g basic rates: 1, 2, 5.5, 11, 6, 12, 24Mbps */ - RAL_WRITE(sc, RT2560_ARSP_PLCP_1, 0x15f); + /* 11b/g basic rates: 1, 2, 5.5, 11Mbps */ + RAL_WRITE(sc, RT2560_ARSP_PLCP_1, 0xf); } } diff --git a/sys/dev/ic/rt2560reg.h b/sys/dev/ic/rt2560reg.h index 61c459c8139..faf478e0ca0 100644 --- a/sys/dev/ic/rt2560reg.h +++ b/sys/dev/ic/rt2560reg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rt2560reg.h,v 1.4 2006/06/10 20:30:00 damien Exp $ */ +/* $OpenBSD: rt2560reg.h,v 1.5 2006/11/13 20:06:38 damien Exp $ */ /*- * Copyright (c) 2005, 2006 @@ -185,7 +185,7 @@ struct rt2560_tx_desc { #define RT2560_TX_FAIL_OTHER (4 << 2) #define RT2560_TX_MORE_FRAG (1 << 8) -#define RT2560_TX_ACK (1 << 9) +#define RT2560_TX_NEED_ACK (1 << 9) #define RT2560_TX_TIMESTAMP (1 << 10) #define RT2560_TX_OFDM (1 << 11) #define RT2560_TX_CIPHER_BUSY (1 << 12) @@ -437,48 +437,3 @@ struct rt2560_rx_desc { 0x0022a, 0x0022a, 0x0022b, 0x0022b, 0x0022c, 0x0022c, 0x0022d \ } -/* - * For dual-band RF, RF registers R1 and R4 also depend on channel number; - * values taken from the reference driver. - */ -#define RT2560_RF5222 \ - { 1, 0x08808, 0x0044d, 0x00282 }, \ - { 2, 0x08808, 0x0044e, 0x00282 }, \ - { 3, 0x08808, 0x0044f, 0x00282 }, \ - { 4, 0x08808, 0x00460, 0x00282 }, \ - { 5, 0x08808, 0x00461, 0x00282 }, \ - { 6, 0x08808, 0x00462, 0x00282 }, \ - { 7, 0x08808, 0x00463, 0x00282 }, \ - { 8, 0x08808, 0x00464, 0x00282 }, \ - { 9, 0x08808, 0x00465, 0x00282 }, \ - { 10, 0x08808, 0x00466, 0x00282 }, \ - { 11, 0x08808, 0x00467, 0x00282 }, \ - { 12, 0x08808, 0x00468, 0x00282 }, \ - { 13, 0x08808, 0x00469, 0x00282 }, \ - { 14, 0x08808, 0x0046b, 0x00286 }, \ - \ - { 36, 0x08804, 0x06225, 0x00287 }, \ - { 40, 0x08804, 0x06226, 0x00287 }, \ - { 44, 0x08804, 0x06227, 0x00287 }, \ - { 48, 0x08804, 0x06228, 0x00287 }, \ - { 52, 0x08804, 0x06229, 0x00287 }, \ - { 56, 0x08804, 0x0622a, 0x00287 }, \ - { 60, 0x08804, 0x0622b, 0x00287 }, \ - { 64, 0x08804, 0x0622c, 0x00287 }, \ - \ - { 100, 0x08804, 0x02200, 0x00283 }, \ - { 104, 0x08804, 0x02201, 0x00283 }, \ - { 108, 0x08804, 0x02202, 0x00283 }, \ - { 112, 0x08804, 0x02203, 0x00283 }, \ - { 116, 0x08804, 0x02204, 0x00283 }, \ - { 120, 0x08804, 0x02205, 0x00283 }, \ - { 124, 0x08804, 0x02206, 0x00283 }, \ - { 128, 0x08804, 0x02207, 0x00283 }, \ - { 132, 0x08804, 0x02208, 0x00283 }, \ - { 136, 0x08804, 0x02209, 0x00283 }, \ - { 140, 0x08804, 0x0220a, 0x00283 }, \ - \ - { 149, 0x08808, 0x02429, 0x00281 }, \ - { 153, 0x08808, 0x0242b, 0x00281 }, \ - { 157, 0x08808, 0x0242d, 0x00281 }, \ - { 161, 0x08808, 0x0242f, 0x00281 } diff --git a/sys/dev/ic/rt2661.c b/sys/dev/ic/rt2661.c index ea7b67825d1..205848824bb 100644 --- a/sys/dev/ic/rt2661.c +++ b/sys/dev/ic/rt2661.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rt2661.c,v 1.30 2006/10/30 20:15:22 damien Exp $ */ +/* $OpenBSD: rt2661.c,v 1.31 2006/11/13 20:06:38 damien Exp $ */ /*- * Copyright (c) 2006 @@ -106,7 +106,7 @@ void rt2661_mcu_wakeup(struct rt2661_softc *); void rt2661_mcu_cmd_intr(struct rt2661_softc *); int rt2661_intr(void *); #if NBPFILTER > 0 -uint8_t rt2661_rxrate(struct rt2661_rx_desc *); +uint8_t rt2661_rxrate(const struct rt2661_rx_desc *); #endif int rt2661_ack_rate(struct ieee80211com *, int); uint16_t rt2661_txtime(int, int, uint32_t); @@ -116,8 +116,6 @@ void rt2661_setup_tx_desc(struct rt2661_softc *, const bus_dma_segment_t *, int, int); int rt2661_tx_mgt(struct rt2661_softc *, struct mbuf *, struct ieee80211_node *); -struct mbuf *rt2661_get_rts(struct rt2661_softc *, - struct ieee80211_frame *, uint16_t); int rt2661_tx_data(struct rt2661_softc *, struct mbuf *, struct ieee80211_node *, int); void rt2661_start(struct ifnet *); @@ -345,7 +343,6 @@ rt2661_attach(void *xsc, int id) printf("%s: WARNING: unable to establish shutdown hook\n", sc->sc_dev.dv_xname); } - sc->sc_powerhook = powerhook_establish(rt2661_power, sc); if (sc->sc_powerhook == NULL) { printf("%s: WARNING: unable to establish power hook\n", @@ -462,13 +459,11 @@ fail: rt2661_free_tx_ring(sc, ring); void rt2661_reset_tx_ring(struct rt2661_softc *sc, struct rt2661_tx_ring *ring) { - struct rt2661_tx_desc *desc; - struct rt2661_tx_data *data; int i; for (i = 0; i < ring->count; i++) { - desc = &ring->desc[i]; - data = &ring->data[i]; + struct rt2661_tx_desc *desc = &ring->desc[i]; + struct rt2661_tx_data *data = &ring->data[i]; if (data->m != NULL) { bus_dmamap_sync(sc->sc_dmat, data->map, 0, @@ -497,7 +492,6 @@ rt2661_reset_tx_ring(struct rt2661_softc *sc, struct rt2661_tx_ring *ring) void rt2661_free_tx_ring(struct rt2661_softc *sc, struct rt2661_tx_ring *ring) { - struct rt2661_tx_data *data; int i; if (ring->desc != NULL) { @@ -511,7 +505,7 @@ rt2661_free_tx_ring(struct rt2661_softc *sc, struct rt2661_tx_ring *ring) if (ring->data != NULL) { for (i = 0; i < ring->count; i++) { - data = &ring->data[i]; + struct rt2661_tx_data *data = &ring->data[i]; if (data->m != NULL) { bus_dmamap_sync(sc->sc_dmat, data->map, 0, @@ -520,7 +514,6 @@ rt2661_free_tx_ring(struct rt2661_softc *sc, struct rt2661_tx_ring *ring) bus_dmamap_unload(sc->sc_dmat, data->map); m_freem(data->m); } - /* * The node has already been freed at that point so * don't call ieee80211_release_node() here. @@ -538,8 +531,6 @@ int rt2661_alloc_rx_ring(struct rt2661_softc *sc, struct rt2661_rx_ring *ring, int count) { - struct rt2661_rx_desc *desc; - struct rt2661_rx_data *data; int i, nsegs, error; ring->count = count; @@ -595,8 +586,8 @@ rt2661_alloc_rx_ring(struct rt2661_softc *sc, struct rt2661_rx_ring *ring, */ memset(ring->data, 0, count * sizeof (struct rt2661_rx_data)); for (i = 0; i < count; i++) { - desc = &sc->rxq.desc[i]; - data = &sc->rxq.data[i]; + struct rt2661_rx_desc *desc = &sc->rxq.desc[i]; + struct rt2661_rx_data *data = &sc->rxq.data[i]; error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES, 0, BUS_DMA_NOWAIT, &data->map); @@ -613,7 +604,6 @@ rt2661_alloc_rx_ring(struct rt2661_softc *sc, struct rt2661_rx_ring *ring, error = ENOMEM; goto fail; } - MCLGET(data->m, M_DONTWAIT); if (!(data->m->m_flags & M_EXT)) { printf("%s: could not allocate rx mbuf cluster\n", @@ -660,7 +650,6 @@ rt2661_reset_rx_ring(struct rt2661_softc *sc, struct rt2661_rx_ring *ring) void rt2661_free_rx_ring(struct rt2661_softc *sc, struct rt2661_rx_ring *ring) { - struct rt2661_rx_data *data; int i; if (ring->desc != NULL) { @@ -674,7 +663,7 @@ rt2661_free_rx_ring(struct rt2661_softc *sc, struct rt2661_rx_ring *ring) if (ring->data != NULL) { for (i = 0; i < ring->count; i++) { - data = &ring->data[i]; + struct rt2661_rx_data *data = &ring->data[i]; if (data->m != NULL) { bus_dmamap_sync(sc->sc_dmat, data->map, 0, @@ -798,11 +787,10 @@ rt2661_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) ostate = ic->ic_state; timeout_del(&sc->scan_to); + timeout_del(&sc->amrr_to); switch (nstate) { case IEEE80211_S_INIT: - timeout_del(&sc->amrr_to); - if (ostate == IEEE80211_S_RUN) { /* abort TSF synchronization */ tmp = RAL_READ(sc, RT2661_TXRX_CSR9); @@ -920,11 +908,10 @@ rt2661_tx_intr(struct rt2661_softc *sc) struct rt2661_tx_ring *txq; struct rt2661_tx_data *data; struct rt2661_node *rn; - uint32_t val; int qid, retrycnt; for (;;) { - val = RAL_READ(sc, RT2661_STA_CSR4); + const uint32_t val = RAL_READ(sc, RT2661_STA_CSR4); if (!(val & RT2661_TX_STAT_VALID)) break; @@ -985,12 +972,9 @@ rt2661_tx_intr(struct rt2661_softc *sc) void rt2661_tx_dma_intr(struct rt2661_softc *sc, struct rt2661_tx_ring *txq) { - struct rt2661_tx_desc *desc; - struct rt2661_tx_data *data; - for (;;) { - desc = &txq->desc[txq->next]; - data = &txq->data[txq->next]; + struct rt2661_tx_desc *desc = &txq->desc[txq->next]; + struct rt2661_tx_data *data = &txq->data[txq->next]; bus_dmamap_sync(sc->sc_dmat, txq->map, txq->next * RT2661_TX_DESC_SIZE, RT2661_TX_DESC_SIZE, @@ -1026,16 +1010,14 @@ rt2661_rx_intr(struct rt2661_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = &ic->ic_if; - struct rt2661_rx_desc *desc; - struct rt2661_rx_data *data; struct ieee80211_frame *wh; struct ieee80211_node *ni; struct mbuf *mnew, *m; int error, rssi; for (;;) { - desc = &sc->rxq.desc[sc->rxq.cur]; - data = &sc->rxq.data[sc->rxq.cur]; + struct rt2661_rx_desc *desc = &sc->rxq.desc[sc->rxq.cur]; + struct rt2661_rx_data *data = &sc->rxq.data[sc->rxq.cur]; bus_dmamap_sync(sc->sc_dmat, sc->rxq.map, sc->rxq.cur * RT2661_RX_DESC_SIZE, RT2661_RX_DESC_SIZE, @@ -1073,7 +1055,6 @@ rt2661_rx_intr(struct rt2661_softc *sc) ifp->if_ierrors++; goto skip; } - MCLGET(mnew, M_DONTWAIT); if (!(mnew->m_flags & M_EXT)) { m_freem(mnew); @@ -1298,7 +1279,7 @@ rt2661_intr(void *arg) */ #if NBPFILTER > 0 uint8_t -rt2661_rxrate(struct rt2661_rx_desc *desc) +rt2661_rxrate(const struct rt2661_rx_desc *desc) { if (letoh32(desc->flags) & RT2661_RX_OFDM) { /* reverse function of rt2661_plcp_signal */ @@ -1328,7 +1309,6 @@ rt2661_rxrate(struct rt2661_rx_desc *desc) /* * Return the expected ack rate for a frame transmitted at rate `rate'. - * XXX: this should depend on the destination node basic rate set. */ int rt2661_ack_rate(struct ieee80211com *ic, int rate) @@ -1567,38 +1547,6 @@ rt2661_tx_mgt(struct rt2661_softc *sc, struct mbuf *m0, return 0; } -/* - * Build a RTS control frame. - */ -struct mbuf * -rt2661_get_rts(struct rt2661_softc *sc, struct ieee80211_frame *wh, - uint16_t dur) -{ - struct ieee80211_frame_rts *rts; - struct mbuf *m; - - MGETHDR(m, M_DONTWAIT, MT_DATA); - if (m == NULL) { - sc->sc_ic.ic_stats.is_tx_nombuf++; - printf("%s: could not allocate RTS frame\n", - sc->sc_dev.dv_xname); - return NULL; - } - - rts = mtod(m, struct ieee80211_frame_rts *); - - rts->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_CTL | - IEEE80211_FC0_SUBTYPE_RTS; - rts->i_fc[1] = IEEE80211_FC1_DIR_NODS; - *(uint16_t *)rts->i_dur = htole16(dur); - IEEE80211_ADDR_COPY(rts->i_ra, wh->i_addr1); - IEEE80211_ADDR_COPY(rts->i_ta, wh->i_addr2); - - m->m_pkthdr.len = m->m_len = sizeof (struct ieee80211_frame_rts); - - return m; -} - int rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, int ac) @@ -1612,17 +1560,10 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0, struct mbuf *mnew; uint16_t dur; uint32_t flags = 0; - int rate, useprot, error; + int pktlen, rate, needcts = 0, needrts = 0, error; wh = mtod(m0, struct ieee80211_frame *); - if (ic->ic_fixed_rate != -1) { - rate = ic->ic_sup_rates[ic->ic_curmode]. - rs_rates[ic->ic_fixed_rate]; - } else - rate = ni->ni_rates.rs_rates[ni->ni_txrate]; - rate &= IEEE80211_RATE_VAL; - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { m0 = ieee80211_wep_crypt(ifp, m0, 1); if (m0 == NULL) @@ -1632,6 +1573,20 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0, wh = mtod(m0, struct ieee80211_frame *); } + /* compute actual packet length (including CRC and crypto overhead) */ + pktlen = m0->m_pkthdr.len + IEEE80211_CRC_LEN; + + /* pickup a rate */ + if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { + /* multicast frames are sent at the lowest avail. rate */ + rate = ni->ni_rates.rs_rates[0]; + } else if (ic->ic_fixed_rate != -1) { + rate = ic->ic_sup_rates[ic->ic_curmode]. + rs_rates[ic->ic_fixed_rate]; + } else + rate = ni->ni_rates.rs_rates[ni->ni_txrate]; + rate &= IEEE80211_RATE_VAL; + /* * Packet Bursting: backoff after ppb=8 frames to give other STAs a * chance to contend for the wireless medium. @@ -1639,34 +1594,39 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0, if (ic->ic_opmode == IEEE80211_M_STA && (ni->ni_txseq & 7)) flags |= RT2661_TX_IFS_SIFS; - /*- - * 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. - * - * 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". - */ - 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; + /* check if RTS/CTS or CTS-to-self protection must be used */ + if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { + /* multicast frames are not sent at OFDM rates in 802.11b/g */ + if (pktlen > ic->ic_rtsthreshold) { + needrts = 1; /* RTS/CTS based on frame length */ + } else if ((ic->ic_flags & IEEE80211_F_USEPROT) && + RAL_RATE_IS_OFDM(rate)) { + if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) + needcts = 1; /* CTS-to-self */ + else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) + needrts = 1; /* RTS/CTS */ + } + } + if (needrts || needcts) { + struct mbuf *mprot; + int protrate, ackrate; uint16_t dur; - int rtsrate, ackrate; - rtsrate = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? 12 : 2; - ackrate = rt2661_ack_rate(ic, rate); + protrate = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? 12 : 2; + ackrate = rt2661_ack_rate(ic, rate); - dur = rt2661_txtime(m0->m_pkthdr.len + 4, rate, ic->ic_flags) + - rt2661_txtime(RAL_CTS_SIZE, rtsrate, ic->ic_flags) + + dur = rt2661_txtime(pktlen, rate, ic->ic_flags) + rt2661_txtime(RAL_ACK_SIZE, ackrate, ic->ic_flags) + - 3 * sc->sifs; - - m = rt2661_get_rts(sc, wh, dur); - if (m == NULL) { - printf("%s: could not allocate RTS frame\n", + 2 * sc->sifs; + if (needrts) { + dur += rt2661_txtime(RAL_CTS_SIZE, rt2661_ack_rate(ic, + protrate), ic->ic_flags) + sc->sifs; + mprot = ieee80211_get_rts(ic, wh, dur); + } else { + mprot = ieee80211_get_cts_to_self(ic, dur); + } + if (mprot == NULL) { + printf("%s: could not allocate protection frame\n", sc->sc_dev.dv_xname); m_freem(m0); return ENOBUFS; @@ -1675,25 +1635,26 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0, desc = &txq->desc[txq->cur]; data = &txq->data[txq->cur]; - error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, m, + error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, mprot, BUS_DMA_NOWAIT); if (error != 0) { printf("%s: could not map mbuf (error %d)\n", sc->sc_dev.dv_xname, error); - m_freem(m); + m_freem(mprot); m_freem(m0); return error; } + data->m = mprot; /* avoid multiple free() of the same node for each fragment */ - ieee80211_ref_node(ni); + data->ni = ieee80211_ref_node(ni); - data->m = m; - data->ni = ni; + /* XXX may want to pass the protection frame to BPF */ - rt2661_setup_tx_desc(sc, desc, RT2661_TX_NEED_ACK | - RT2661_TX_MORE_FRAG, 0, m->m_pkthdr.len, rtsrate, - data->map->dm_segs, data->map->dm_nsegs, ac); + rt2661_setup_tx_desc(sc, desc, + (needrts ? RT2661_TX_NEED_ACK : 0) | RT2661_TX_MORE_FRAG, + 0, mprot->m_pkthdr.len, protrate, data->map->dm_segs, + data->map->dm_nsegs, ac); bus_dmamap_sync(sc->sc_dmat, data->map, 0, data->map->dm_mapsize, BUS_DMASYNC_PREWRITE); @@ -1726,7 +1687,6 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0, m_freem(m0); return ENOMEM; } - M_DUP_PKTHDR(mnew, m0); if (m0->m_pkthdr.len > MHLEN) { MCLGET(mnew, M_DONTWAIT); @@ -2124,12 +2084,12 @@ rt2661_set_basicrates(struct rt2661_softc *sc) if (ic->ic_curmode == IEEE80211_MODE_11B) { /* 11b basic rates: 1, 2Mbps */ RAL_WRITE(sc, RT2661_TXRX_CSR5, 0x3); - } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_bss->ni_chan)) { + } else if (ic->ic_curmode == IEEE80211_MODE_11A) { /* 11a basic rates: 6, 12, 24Mbps */ RAL_WRITE(sc, RT2661_TXRX_CSR5, 0x150); } else { - /* 11g basic rates: 1, 2, 5.5, 11, 6, 12, 24Mbps */ - RAL_WRITE(sc, RT2661_TXRX_CSR5, 0x15f); + /* 11b/g basic rates: 1, 2, 5.5, 11Mbps */ + RAL_WRITE(sc, RT2661_TXRX_CSR5, 0xf); } } @@ -2433,11 +2393,10 @@ rt2661_bbp_init(struct rt2661_softc *sc) { #define N(a) (sizeof (a) / sizeof ((a)[0])) int i, ntries; - uint8_t val; /* wait for BBP to be ready */ for (ntries = 0; ntries < 100; ntries++) { - val = rt2661_bbp_read(sc, 0); + const uint8_t val = rt2661_bbp_read(sc, 0); if (val != 0 && val != 0xff) break; DELAY(100); diff --git a/sys/dev/pci/if_wpi.c b/sys/dev/pci/if_wpi.c index 8fb7b06bc17..8d5d6497f8a 100644 --- a/sys/dev/pci/if_wpi.c +++ b/sys/dev/pci/if_wpi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_wpi.c,v 1.35 2006/11/01 11:25:01 damien Exp $ */ +/* $OpenBSD: if_wpi.c,v 1.36 2006/11/13 20:06:38 damien Exp $ */ /*- * Copyright (c) 2006 @@ -1457,17 +1457,16 @@ wpi_tx_data(struct wpi_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, } /* pickup a rate */ - if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == - IEEE80211_FC0_TYPE_MGT) { - /* mgmt frames are sent at the lowest available bit-rate */ + if (IEEE80211_IS_MULTICAST(wh->i_addr1) || + ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == + IEEE80211_FC0_TYPE_MGT)) { + /* mgmt/multicast frames are sent at the lowest avail. rate */ rate = ni->ni_rates.rs_rates[0]; - } else { - if (ic->ic_fixed_rate != -1) { - rate = ic->ic_sup_rates[ic->ic_curmode]. - rs_rates[ic->ic_fixed_rate]; - } else - rate = ni->ni_rates.rs_rates[ni->ni_txrate]; - } + } else if (ic->ic_fixed_rate != -1) { + rate = ic->ic_sup_rates[ic->ic_curmode]. + rs_rates[ic->ic_fixed_rate]; + } else + rate = ni->ni_rates.rs_rates[ni->ni_txrate]; rate &= IEEE80211_RATE_VAL; #if NBPFILTER > 0 @@ -1504,15 +1503,27 @@ wpi_tx_data(struct wpi_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { tx->id = WPI_ID_BSS; tx->flags |= htole32(WPI_TX_NEED_ACK); + } else + tx->id = WPI_ID_BROADCAST; + /* check if RTS/CTS or CTS-to-self protection must be used */ + if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { + /* multicast frames are not sent at OFDM rates in 802.11b/g */ if (m0->m_pkthdr.len + IEEE80211_CRC_LEN > - ic->ic_rtsthreshold || (WPI_RATE_IS_OFDM(rate) && - (ic->ic_flags & IEEE80211_F_USEPROT))) { + ic->ic_rtsthreshold) { tx->flags |= htole32(WPI_TX_NEED_RTS | WPI_TX_FULL_TXOP); + } else if ((ic->ic_flags & IEEE80211_F_USEPROT) && + WPI_RATE_IS_OFDM(rate)) { + if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) { + tx->flags |= htole32(WPI_TX_NEED_CTS | + WPI_TX_FULL_TXOP); + } else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) { + tx->flags |= htole32(WPI_TX_NEED_RTS | + WPI_TX_FULL_TXOP); + } } - } else - tx->id = WPI_ID_BROADCAST; + } tx->flags |= htole32(WPI_TX_AUTO_SEQ); diff --git a/sys/dev/pci/if_wpireg.h b/sys/dev/pci/if_wpireg.h index 72c911990c5..8c285e47623 100644 --- a/sys/dev/pci/if_wpireg.h +++ b/sys/dev/pci/if_wpireg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_wpireg.h,v 1.11 2006/08/28 19:47:43 damien Exp $ */ +/* $OpenBSD: if_wpireg.h,v 1.12 2006/11/13 20:06:38 damien Exp $ */ /*- * Copyright (c) 2006 @@ -355,6 +355,7 @@ struct wpi_cmd_data { uint16_t lnext; uint32_t flags; #define WPI_TX_NEED_RTS (1 << 1) +#define WPI_TX_NEED_CTS (1 << 2) #define WPI_TX_NEED_ACK (1 << 3) #define WPI_TX_FULL_TXOP (1 << 7) #define WPI_TX_AUTO_SEQ (1 << 13) diff --git a/sys/dev/usb/if_ral.c b/sys/dev/usb/if_ral.c index 59f013ae06d..ff52ab1d6fd 100644 --- a/sys/dev/usb/if_ral.c +++ b/sys/dev/usb/if_ral.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ral.c,v 1.81 2006/10/22 12:27:56 damien Exp $ */ +/* $OpenBSD: if_ral.c,v 1.82 2006/11/13 20:06:38 damien Exp $ */ /*- * Copyright (c) 2005, 2006 @@ -123,7 +123,7 @@ Static void ural_txeof(usbd_xfer_handle, usbd_private_handle, Static void ural_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); #if NBPFILTER > 0 -Static uint8_t ural_rxrate(struct ural_rx_desc *); +Static uint8_t ural_rxrate(const struct ural_rx_desc *); #endif Static int ural_ack_rate(struct ieee80211com *, int); Static uint16_t ural_txtime(int, int, uint32_t); @@ -155,8 +155,8 @@ Static void ural_enable_tsf_sync(struct ural_softc *); Static void ural_update_slot(struct ural_softc *); Static void ural_set_txpreamble(struct ural_softc *); Static void ural_set_basicrates(struct ural_softc *); -Static void ural_set_bssid(struct ural_softc *, uint8_t *); -Static void ural_set_macaddr(struct ural_softc *, uint8_t *); +Static void ural_set_bssid(struct ural_softc *, const uint8_t *); +Static void ural_set_macaddr(struct ural_softc *, const uint8_t *); Static void ural_update_promisc(struct ural_softc *); Static const char *ural_get_rf(int); Static void ural_read_eeprom(struct ural_softc *); @@ -174,11 +174,8 @@ Static void ural_amrr_update(usbd_xfer_handle, usbd_private_handle, usbd_status status); /* - * Supported rates for 802.11a/b/g modes (in 500Kbps unit). + * Supported rates for 802.11b/g modes (in 500Kbps unit). */ -static const struct ieee80211_rateset ural_rateset_11a = - { 8, { 12, 18, 24, 36, 48, 72, 96, 108 } }; - static const struct ieee80211_rateset ural_rateset_11b = { 4, { 2, 4, 11, 22 } }; @@ -208,13 +205,6 @@ static const uint32_t ural_rf2525e_r2[] = RAL_RF2525E_R2; static const uint32_t ural_rf2526_hi_r2[] = RAL_RF2526_HI_R2; static const uint32_t ural_rf2526_r2[] = RAL_RF2526_R2; -static const struct { - uint8_t chan; - uint32_t r1, r2, r4; -} ural_rf5222[] = { - RAL_RF5222 -}; - USB_DECLARE_DRIVER_CLASS(ural, DV_IFNET); USB_MATCH(ural) @@ -288,11 +278,11 @@ USB_ATTACH(ural) } usb_init_task(&sc->sc_task, ural_task, sc); - timeout_set(&sc->scan_ch, ural_next_scan, sc); + timeout_set(&sc->scan_to, ural_next_scan, sc); sc->amrr.amrr_min_success_threshold = 1; sc->amrr.amrr_max_success_threshold = 10; - timeout_set(&sc->amrr_ch, ural_amrr_timeout, sc); + timeout_set(&sc->amrr_to, ural_amrr_timeout, sc); /* retrieve RT2570 rev. no */ sc->asic_rev = ural_read(sc, RAL_MAC_CSR0); @@ -318,28 +308,6 @@ USB_ATTACH(ural) IEEE80211_C_SHSLOT | /* short slot time supported */ IEEE80211_C_WEP; /* s/w WEP */ - if (sc->rf_rev == RAL_RF_5222) { - /* set supported .11a rates */ - ic->ic_sup_rates[IEEE80211_MODE_11A] = ural_rateset_11a; - - /* set supported .11a channels */ - for (i = 36; i <= 64; i += 4) { - ic->ic_channels[i].ic_freq = - ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ); - ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A; - } - for (i = 100; i <= 140; i += 4) { - ic->ic_channels[i].ic_freq = - ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ); - ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A; - } - for (i = 149; i <= 161; i += 4) { - ic->ic_channels[i].ic_freq = - ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ); - ic->ic_channels[i].ic_flags = IEEE80211_CHAN_A; - } - } - /* set supported .11b and .11g rates */ ic->ic_sup_rates[IEEE80211_MODE_11B] = ural_rateset_11b; ic->ic_sup_rates[IEEE80211_MODE_11G] = ural_rateset_11g; @@ -402,8 +370,8 @@ USB_DETACH(ural) if_detach(ifp); usb_rem_task(sc->sc_udev, &sc->sc_task); - timeout_del(&sc->scan_ch); - timeout_del(&sc->amrr_ch); + timeout_del(&sc->scan_to); + timeout_del(&sc->amrr_to); if (sc->amrr_xfer != NULL) { usbd_free_xfer(sc->amrr_xfer); @@ -434,13 +402,12 @@ USB_DETACH(ural) Static int ural_alloc_tx_list(struct ural_softc *sc) { - struct ural_tx_data *data; int i, error; - sc->tx_queued = 0; + sc->tx_cur = sc->tx_queued = 0; for (i = 0; i < RAL_TX_LIST_COUNT; i++) { - data = &sc->tx_data[i]; + struct ural_tx_data *data = &sc->tx_data[i]; data->sc = sc; @@ -451,7 +418,6 @@ ural_alloc_tx_list(struct ural_softc *sc) error = ENOMEM; goto fail; } - data->buf = usbd_alloc_buffer(data->xfer, RAL_TX_DESC_SIZE + IEEE80211_MAX_LEN); if (data->buf == NULL) { @@ -471,17 +437,15 @@ fail: ural_free_tx_list(sc); Static void ural_free_tx_list(struct ural_softc *sc) { - struct ural_tx_data *data; int i; for (i = 0; i < RAL_TX_LIST_COUNT; i++) { - data = &sc->tx_data[i]; + struct ural_tx_data *data = &sc->tx_data[i]; if (data->xfer != NULL) { usbd_free_xfer(data->xfer); data->xfer = NULL; } - /* * The node has already been freed at that point so don't call * ieee80211_release_node() here. @@ -493,11 +457,10 @@ ural_free_tx_list(struct ural_softc *sc) Static int ural_alloc_rx_list(struct ural_softc *sc) { - struct ural_rx_data *data; int i, error; for (i = 0; i < RAL_RX_LIST_COUNT; i++) { - data = &sc->rx_data[i]; + struct ural_rx_data *data = &sc->rx_data[i]; data->sc = sc; @@ -508,7 +471,6 @@ ural_alloc_rx_list(struct ural_softc *sc) error = ENOMEM; goto fail; } - if (usbd_alloc_buffer(data->xfer, MCLBYTES) == NULL) { printf("%s: could not allocate rx buffer\n", USBDEVNAME(sc->sc_dev)); @@ -523,7 +485,6 @@ ural_alloc_rx_list(struct ural_softc *sc) error = ENOMEM; goto fail; } - MCLGET(data->m, M_DONTWAIT); if (!(data->m->m_flags & M_EXT)) { printf("%s: could not allocate rx mbuf cluster\n", @@ -531,7 +492,6 @@ ural_alloc_rx_list(struct ural_softc *sc) error = ENOMEM; goto fail; } - data->buf = mtod(data->m, uint8_t *); } @@ -544,17 +504,15 @@ fail: ural_free_tx_list(sc); Static void ural_free_rx_list(struct ural_softc *sc) { - struct ural_rx_data *data; int i; for (i = 0; i < RAL_RX_LIST_COUNT; i++) { - data = &sc->rx_data[i]; + struct ural_rx_data *data = &sc->rx_data[i]; if (data->xfer != NULL) { usbd_free_xfer(data->xfer); data->xfer = NULL; } - if (data->m != NULL) { m_freem(data->m); data->m = NULL; @@ -616,7 +574,7 @@ ural_task(void *arg) case IEEE80211_S_SCAN: ural_set_chan(sc, ic->ic_bss->ni_chan); - timeout_add(&sc->scan_ch, hz / 5); + timeout_add(&sc->scan_to, hz / 5); break; case IEEE80211_S_AUTH: @@ -686,8 +644,8 @@ ural_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) struct ural_softc *sc = ic->ic_if.if_softc; usb_rem_task(sc->sc_udev, &sc->sc_task); - timeout_del(&sc->scan_ch); - timeout_del(&sc->amrr_ch); + timeout_del(&sc->scan_to); + timeout_del(&sc->amrr_to); /* do it in a process context */ sc->sc_state = nstate; @@ -732,8 +690,6 @@ ural_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) s = splnet(); - m_freem(data->m); - data->m = NULL; ieee80211_release_node(ic, data->ni); data->ni = NULL; @@ -756,7 +712,7 @@ ural_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) struct ural_softc *sc = data->sc; struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = &ic->ic_if; - struct ural_rx_desc *desc; + const struct ural_rx_desc *desc; struct ieee80211_frame *wh; struct ieee80211_node *ni; struct mbuf *mnew, *m; @@ -800,7 +756,6 @@ ural_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) ifp->if_ierrors++; goto skip; } - MCLGET(mnew, M_DONTWAIT); if (!(mnew->m_flags & M_EXT)) { printf("%s: could not allocate rx mbuf cluster\n", @@ -809,7 +764,6 @@ ural_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) ifp->if_ierrors++; goto skip; } - m = data->m; data->m = mnew; data->buf = mtod(data->m, uint8_t *); @@ -865,7 +819,7 @@ ural_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) skip: /* setup a new transfer */ usbd_setup_xfer(xfer, sc->sc_rx_pipeh, data, data->buf, MCLBYTES, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, ural_rxeof); - usbd_transfer(xfer); + (void)usbd_transfer(xfer); } /* @@ -874,7 +828,7 @@ skip: /* setup a new transfer */ */ #if NBPFILTER > 0 Static uint8_t -ural_rxrate(struct ural_rx_desc *desc) +ural_rxrate(const struct ural_rx_desc *desc) { if (letoh32(desc->flags) & RAL_RX_OFDM) { /* reverse function of ural_plcp_signal */ @@ -904,7 +858,6 @@ ural_rxrate(struct ural_rx_desc *desc) /* * Return the expected ack rate for a frame transmitted at rate `rate'. - * XXX: this should depend on the destination node basic rate set. */ Static int ural_ack_rate(struct ieee80211com *ic, int rate) @@ -995,7 +948,6 @@ ural_setup_tx_desc(struct ural_softc *sc, struct ural_tx_desc *desc, int remainder; desc->flags = htole32(flags); - desc->flags |= htole32(RAL_TX_NEWSEQ); desc->flags |= htole32(len << 16); desc->wme = htole16( @@ -1042,9 +994,7 @@ ural_tx_bcn(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) usbd_status error; uint8_t cmd = 0; uint8_t *buf; - int xferlen, rate; - - rate = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? 12 : 2; + int xferlen, rate = 2; xfer = usbd_alloc_xfer(sc->sc_udev); if (xfer == NULL) @@ -1094,10 +1044,10 @@ ural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) struct ural_tx_desc *desc; struct ural_tx_data *data; struct ieee80211_frame *wh; - uint32_t flags = 0; + uint32_t flags = RAL_TX_NEWSEQ; uint16_t dur; usbd_status error; - int xferlen, rate; + int rate, xferlen, pktlen, needrts = 0, needcts = 0; wh = mtod(m0, struct ieee80211_frame *); @@ -1110,30 +1060,102 @@ ural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) wh = mtod(m0, struct ieee80211_frame *); } + /* compute actual packet length (including CRC and crypto overhead) */ + pktlen = m0->m_pkthdr.len + IEEE80211_CRC_LEN; + /* pickup a rate */ - if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == - IEEE80211_FC0_TYPE_MGT) { - /* mgmt frames are sent at the lowest available bit-rate */ + if (IEEE80211_IS_MULTICAST(wh->i_addr1) || + ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == + IEEE80211_FC0_TYPE_MGT)) { + /* mgmt/multicast frames are sent at the lowest avail. rate */ rate = ni->ni_rates.rs_rates[0]; - } else { - if (ic->ic_fixed_rate != -1) { - rate = ic->ic_sup_rates[ic->ic_curmode]. - rs_rates[ic->ic_fixed_rate]; - } else + } else if (ic->ic_fixed_rate != -1) { + rate = ic->ic_sup_rates[ic->ic_curmode]. + rs_rates[ic->ic_fixed_rate]; + } else rate = ni->ni_rates.rs_rates[ni->ni_txrate]; - } rate &= IEEE80211_RATE_VAL; - if (rate == 0) - rate = 2; /* fallback to 1Mbps; should not happen */ - data = &sc->tx_data[0]; + /* check if RTS/CTS or CTS-to-self protection must be used */ + if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { + /* multicast frames are not sent at OFDM rates in 802.11b/g */ + if (pktlen > ic->ic_rtsthreshold) { + needrts = 1; /* RTS/CTS based on frame length */ + } else if ((ic->ic_flags & IEEE80211_F_USEPROT) && + RAL_RATE_IS_OFDM(rate)) { + if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) + needcts = 1; /* CTS-to-self */ + else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) + needrts = 1; /* RTS/CTS */ + } + } + if (needrts || needcts) { + struct mbuf *mprot; + int protrate, ackrate; + uint16_t dur; + + protrate = 2; + ackrate = ural_ack_rate(ic, rate); + + dur = ural_txtime(pktlen, rate, ic->ic_flags) + + ural_txtime(RAL_ACK_SIZE, ackrate, ic->ic_flags) + + 2 * RAL_SIFS; + if (needrts) { + dur += ural_txtime(RAL_CTS_SIZE, ural_ack_rate(ic, + protrate), ic->ic_flags) + RAL_SIFS; + mprot = ieee80211_get_rts(ic, wh, dur); + } else { + mprot = ieee80211_get_cts_to_self(ic, dur); + } + if (mprot == NULL) { + printf("%s: could not allocate protection frame\n", + sc->sc_dev.dv_xname); + m_freem(m0); + return ENOBUFS; + } + + data = &sc->tx_data[sc->tx_cur]; + desc = (struct ural_tx_desc *)data->buf; + + /* avoid multiple free() of the same node for each fragment */ + data->ni = ieee80211_ref_node(ni); + + m_copydata(mprot, 0, mprot->m_pkthdr.len, + data->buf + RAL_TX_DESC_SIZE); + ural_setup_tx_desc(sc, desc, + (needrts ? RAL_TX_NEED_ACK : 0) | RAL_TX_RETRY(7), + mprot->m_pkthdr.len, protrate); + + /* no roundup necessary here */ + xferlen = RAL_TX_DESC_SIZE + mprot->m_pkthdr.len; + + /* XXX may want to pass the protection frame to BPF */ + + /* mbuf is no longer needed */ + m_freem(mprot); + + usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf, + xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, + RAL_TX_TIMEOUT, ural_txeof); + error = usbd_transfer(data->xfer); + if (error != 0 && error != USBD_IN_PROGRESS) { + m_freem(m0); + return error; + } + + sc->tx_queued++; + sc->tx_cur = (sc->tx_cur + 1) % RAL_TX_LIST_COUNT; + + flags |= RAL_TX_IFS_SIFS; + } + + data = &sc->tx_data[sc->tx_cur]; desc = (struct ural_tx_desc *)data->buf; - data->m = m0; data->ni = ni; if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { - flags |= RAL_TX_ACK; + flags |= RAL_TX_NEED_ACK; flags |= RAL_TX_RETRY(7); dur = ural_txtime(RAL_ACK_SIZE, ural_ack_rate(ic, rate), @@ -1183,16 +1205,17 @@ ural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) DPRINTFN(10, ("sending frame len=%u rate=%u xfer len=%u\n", m0->m_pkthdr.len, rate, xferlen)); + /* mbuf is no longer needed */ + m_freem(m0); + usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf, xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RAL_TX_TIMEOUT, ural_txeof); - error = usbd_transfer(data->xfer); - if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) { - m_freem(m0); + if (error != 0 && error != USBD_IN_PROGRESS) return error; - } sc->tx_queued++; + sc->tx_cur = (sc->tx_cur + 1) % RAL_TX_LIST_COUNT; return 0; } @@ -1215,7 +1238,7 @@ ural_start(struct ifnet *ifp) for (;;) { IF_POLL(&ic->ic_mgtq, m0); if (m0 != NULL) { - if (sc->tx_queued >= RAL_TX_LIST_COUNT) { + if (sc->tx_queued >= RAL_TX_LIST_COUNT - 1) { ifp->if_flags |= IFF_OACTIVE; break; } @@ -1236,7 +1259,7 @@ ural_start(struct ifnet *ifp) IFQ_POLL(&ifp->if_snd, m0); if (m0 == NULL) break; - if (sc->tx_queued >= RAL_TX_LIST_COUNT) { + if (sc->tx_queued >= RAL_TX_LIST_COUNT - 1) { ifp->if_flags |= IFF_OACTIVE; break; } @@ -1396,7 +1419,6 @@ ural_read(struct ural_softc *sc, uint16_t reg) USBDEVNAME(sc->sc_dev), usbd_errstr(error)); return 0; } - return le16toh(val); } @@ -1493,7 +1515,6 @@ ural_bbp_read(struct ural_softc *sc, uint8_t reg) printf("%s: could not read BBP\n", USBDEVNAME(sc->sc_dev)); return 0; } - return ural_read(sc, RAL_PHY_CSR7) & 0xff; } @@ -1527,16 +1548,13 @@ ural_set_chan(struct ural_softc *sc, struct ieee80211_channel *c) { struct ieee80211com *ic = &sc->sc_ic; uint8_t power, tmp; - u_int i, chan; + u_int chan; chan = ieee80211_chan2ieee(ic, c); if (chan == 0 || chan == IEEE80211_CHAN_ANY) return; - if (IEEE80211_IS_CHAN_2GHZ(c)) - power = min(sc->txpow[chan - 1], 31); - else - power = 31; + power = min(sc->txpow[chan - 1], 31); DPRINTFN(2, ("setting channel to %u, txpower to %u\n", chan, power)); @@ -1589,16 +1607,6 @@ ural_set_chan(struct ural_softc *sc, struct ieee80211_channel *c) ural_rf_write(sc, RAL_RF3, power << 7 | 0x18044); ural_rf_write(sc, RAL_RF4, (chan & 1) ? 0x00386 : 0x00381); break; - - /* dual-band RF */ - case RAL_RF_5222: - for (i = 0; ural_rf5222[i].chan != chan; i++); - - ural_rf_write(sc, RAL_RF1, ural_rf5222[i].r1); - ural_rf_write(sc, RAL_RF2, ural_rf5222[i].r2); - ural_rf_write(sc, RAL_RF3, power << 7 | 0x00040); - ural_rf_write(sc, RAL_RF4, ural_rf5222[i].r4); - break; } if (ic->ic_opmode != IEEE80211_M_MONITOR && @@ -1719,17 +1727,14 @@ ural_set_basicrates(struct ural_softc *sc) if (ic->ic_curmode == IEEE80211_MODE_11B) { /* 11b basic rates: 1, 2Mbps */ ural_write(sc, RAL_TXRX_CSR11, 0x3); - } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_bss->ni_chan)) { - /* 11a basic rates: 6, 12, 24Mbps */ - ural_write(sc, RAL_TXRX_CSR11, 0x150); } else { - /* 11g basic rates: 1, 2, 5.5, 11, 6, 12, 24Mbps */ - ural_write(sc, RAL_TXRX_CSR11, 0x15f); + /* 11b/g basic rates: 1, 2, 5.5, 11Mbps */ + ural_write(sc, RAL_TXRX_CSR11, 0xf); } } Static void -ural_set_bssid(struct ural_softc *sc, uint8_t *bssid) +ural_set_bssid(struct ural_softc *sc, const uint8_t *bssid) { uint16_t tmp; @@ -1742,11 +1747,11 @@ ural_set_bssid(struct ural_softc *sc, uint8_t *bssid) tmp = bssid[4] | bssid[5] << 8; ural_write(sc, RAL_MAC_CSR7, tmp); - DPRINTF(("setting BSSID to %s\n", ether_sprintf(bssid))); + DPRINTF(("setting BSSID to %s\n", ether_sprintf((uint8_t *)bssid))); } Static void -ural_set_macaddr(struct ural_softc *sc, uint8_t *addr) +ural_set_macaddr(struct ural_softc *sc, const uint8_t *addr) { uint16_t tmp; @@ -1759,7 +1764,8 @@ ural_set_macaddr(struct ural_softc *sc, uint8_t *addr) tmp = addr[4] | addr[5] << 8; ural_write(sc, RAL_MAC_CSR4, tmp); - DPRINTF(("setting MAC address to %s\n", ether_sprintf(addr))); + DPRINTF(("setting MAC address to %s\n", + ether_sprintf((uint8_t *)addr))); } Static void @@ -1913,8 +1919,6 @@ ural_init(struct ifnet *ifp) #define N(a) (sizeof (a) / sizeof ((a)[0])) struct ural_softc *sc = ifp->if_softc; struct ieee80211com *ic = &sc->sc_ic; - struct ieee80211_wepkey *wk; - struct ural_rx_data *data; uint16_t tmp; usbd_status error; int i, ntries; @@ -1970,7 +1974,7 @@ ural_init(struct ifnet *ifp) * Copy WEP keys into adapter's memory (SEC_CSR0 to SEC_CSR31). */ for (i = 0; i < IEEE80211_WEP_NKID; i++) { - wk = &ic->ic_nw_keys[i]; + struct ieee80211_wepkey *wk = &ic->ic_nw_keys[i]; ural_write_multi(sc, RAL_SEC_CSR0 + i * IEEE80211_KEYBUF_SIZE, wk->wk_key, IEEE80211_KEYBUF_SIZE); } @@ -1995,7 +1999,6 @@ ural_init(struct ifnet *ifp) USBDEVNAME(sc->sc_dev), usbd_errstr(error)); goto fail; } - error = usbd_open_pipe(sc->sc_iface, sc->sc_rx_no, USBD_EXCLUSIVE_USE, &sc->sc_rx_pipeh); if (error != 0) { @@ -2013,7 +2016,6 @@ ural_init(struct ifnet *ifp) USBDEVNAME(sc->sc_dev)); goto fail; } - error = ural_alloc_rx_list(sc); if (error != 0) { printf("%s: could not allocate Rx list\n", @@ -2025,11 +2027,16 @@ ural_init(struct ifnet *ifp) * Start up the receive pipe. */ for (i = 0; i < RAL_RX_LIST_COUNT; i++) { - data = &sc->rx_data[i]; + struct ural_rx_data *data = &sc->rx_data[i]; usbd_setup_xfer(data->xfer, sc->sc_rx_pipeh, data, data->buf, MCLBYTES, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, ural_rxeof); - usbd_transfer(data->xfer); + error = usbd_transfer(data->xfer); + if (error != 0 && error != USBD_IN_PROGRESS) { + printf("%s: could not queue Rx transfer\n", + USBDEVNAME(sc->sc_dev)); + goto fail; + } } /* kick Rx */ @@ -2081,13 +2088,11 @@ ural_stop(struct ifnet *ifp, int disable) usbd_free_xfer(sc->amrr_xfer); sc->amrr_xfer = NULL; } - if (sc->sc_rx_pipeh != NULL) { usbd_abort_pipe(sc->sc_rx_pipeh); usbd_close_pipe(sc->sc_rx_pipeh); sc->sc_rx_pipeh = NULL; } - if (sc->sc_tx_pipeh != NULL) { usbd_abort_pipe(sc->sc_tx_pipeh); usbd_close_pipe(sc->sc_tx_pipeh); @@ -2121,7 +2126,7 @@ ural_amrr_start(struct ural_softc *sc, struct ieee80211_node *ni) i--); ni->ni_txrate = i; - timeout_add(&sc->amrr_ch, hz); + timeout_add(&sc->amrr_to, hz); } Static void @@ -2177,7 +2182,7 @@ ural_amrr_update(usbd_xfer_handle xfer, usbd_private_handle priv, ieee80211_amrr_choose(&sc->amrr, sc->sc_ic.ic_bss, &sc->amn); - timeout_add(&sc->amrr_ch, hz); + timeout_add(&sc->amrr_to, hz); } Static int diff --git a/sys/dev/usb/if_ralreg.h b/sys/dev/usb/if_ralreg.h index e2cf5144f99..4dbe14f3491 100644 --- a/sys/dev/usb/if_ralreg.h +++ b/sys/dev/usb/if_ralreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ralreg.h,v 1.11 2006/08/09 07:40:52 damien Exp $ */ +/* $OpenBSD: if_ralreg.h,v 1.12 2006/11/13 20:06:38 damien Exp $ */ /*- * Copyright (c) 2005, 2006 @@ -149,7 +149,7 @@ struct ural_tx_desc { uint32_t flags; #define RAL_TX_RETRY(x) ((x) << 4) #define RAL_TX_MORE_FRAG (1 << 8) -#define RAL_TX_ACK (1 << 9) +#define RAL_TX_NEED_ACK (1 << 9) #define RAL_TX_TIMESTAMP (1 << 10) #define RAL_TX_OFDM (1 << 11) #define RAL_TX_NEWSEQ (1 << 12) @@ -315,49 +315,3 @@ struct ural_rx_desc { 0x00226, 0x00227, 0x00227, 0x00228, 0x00228, 0x00229, 0x00229, \ 0x0022a, 0x0022a, 0x0022b, 0x0022b, 0x0022c, 0x0022c, 0x0022d \ } - -/* - * For dual-band RF, RF registers R1 and R4 also depend on channel number; - * values taken from the reference driver. - */ -#define RAL_RF5222 \ - { 1, 0x08808, 0x0044d, 0x00282 }, \ - { 2, 0x08808, 0x0044e, 0x00282 }, \ - { 3, 0x08808, 0x0044f, 0x00282 }, \ - { 4, 0x08808, 0x00460, 0x00282 }, \ - { 5, 0x08808, 0x00461, 0x00282 }, \ - { 6, 0x08808, 0x00462, 0x00282 }, \ - { 7, 0x08808, 0x00463, 0x00282 }, \ - { 8, 0x08808, 0x00464, 0x00282 }, \ - { 9, 0x08808, 0x00465, 0x00282 }, \ - { 10, 0x08808, 0x00466, 0x00282 }, \ - { 11, 0x08808, 0x00467, 0x00282 }, \ - { 12, 0x08808, 0x00468, 0x00282 }, \ - { 13, 0x08808, 0x00469, 0x00282 }, \ - { 14, 0x08808, 0x0046b, 0x00286 }, \ - \ - { 36, 0x08804, 0x06225, 0x00287 }, \ - { 40, 0x08804, 0x06226, 0x00287 }, \ - { 44, 0x08804, 0x06227, 0x00287 }, \ - { 48, 0x08804, 0x06228, 0x00287 }, \ - { 52, 0x08804, 0x06229, 0x00287 }, \ - { 56, 0x08804, 0x0622a, 0x00287 }, \ - { 60, 0x08804, 0x0622b, 0x00287 }, \ - { 64, 0x08804, 0x0622c, 0x00287 }, \ - \ - { 100, 0x08804, 0x02200, 0x00283 }, \ - { 104, 0x08804, 0x02201, 0x00283 }, \ - { 108, 0x08804, 0x02202, 0x00283 }, \ - { 112, 0x08804, 0x02203, 0x00283 }, \ - { 116, 0x08804, 0x02204, 0x00283 }, \ - { 120, 0x08804, 0x02205, 0x00283 }, \ - { 124, 0x08804, 0x02206, 0x00283 }, \ - { 128, 0x08804, 0x02207, 0x00283 }, \ - { 132, 0x08804, 0x02208, 0x00283 }, \ - { 136, 0x08804, 0x02209, 0x00283 }, \ - { 140, 0x08804, 0x0220a, 0x00283 }, \ - \ - { 149, 0x08808, 0x02429, 0x00281 }, \ - { 153, 0x08808, 0x0242b, 0x00281 }, \ - { 157, 0x08808, 0x0242d, 0x00281 }, \ - { 161, 0x08808, 0x0242f, 0x00281 } diff --git a/sys/dev/usb/if_ralvar.h b/sys/dev/usb/if_ralvar.h index ab7106048d1..9ffa2d1df1e 100644 --- a/sys/dev/usb/if_ralvar.h +++ b/sys/dev/usb/if_ralvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ralvar.h,v 1.7 2006/08/18 15:18:24 damien Exp $ */ +/* $OpenBSD: if_ralvar.h,v 1.8 2006/11/13 20:06:38 damien Exp $ */ /*- * Copyright (c) 2005 @@ -18,7 +18,7 @@ */ #define RAL_RX_LIST_COUNT 1 -#define RAL_TX_LIST_COUNT 1 +#define RAL_TX_LIST_COUNT 8 struct ural_rx_radiotap_header { struct ieee80211_radiotap_header wr_ihdr; @@ -58,7 +58,6 @@ struct ural_tx_data { struct ural_softc *sc; usbd_xfer_handle xfer; uint8_t *buf; - struct mbuf *m; struct ieee80211_node *ni; }; @@ -100,9 +99,10 @@ struct ural_softc { struct ural_rx_data rx_data[RAL_RX_LIST_COUNT]; struct ural_tx_data tx_data[RAL_TX_LIST_COUNT]; int tx_queued; + int tx_cur; - struct timeout scan_ch; - struct timeout amrr_ch; + struct timeout scan_to; + struct timeout amrr_to; int sc_tx_timer; diff --git a/sys/dev/usb/if_rum.c b/sys/dev/usb/if_rum.c index b2e294ab8a9..b480ef90dd8 100644 --- a/sys/dev/usb/if_rum.c +++ b/sys/dev/usb/if_rum.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_rum.c,v 1.42 2006/10/22 12:27:56 damien Exp $ */ +/* $OpenBSD: if_rum.c,v 1.43 2006/11/13 20:06:38 damien Exp $ */ /*- * Copyright (c) 2005, 2006 Damien Bergamini <damien.bergamini@free.fr> @@ -124,7 +124,7 @@ Static void rum_txeof(usbd_xfer_handle, usbd_private_handle, Static void rum_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); #if NBPFILTER > 0 -Static uint8_t rum_rxrate(struct rum_rx_desc *); +Static uint8_t rum_rxrate(const struct rum_rx_desc *); #endif Static int rum_ack_rate(struct ieee80211com *, int); Static uint16_t rum_txtime(int, int, uint32_t); @@ -309,11 +309,11 @@ USB_ATTACH(rum) } usb_init_task(&sc->sc_task, rum_task, sc); - timeout_set(&sc->scan_ch, rum_next_scan, sc); + timeout_set(&sc->scan_to, rum_next_scan, sc); sc->amrr.amrr_min_success_threshold = 1; sc->amrr.amrr_max_success_threshold = 10; - timeout_set(&sc->amrr_ch, rum_amrr_timeout, sc); + timeout_set(&sc->amrr_to, rum_amrr_timeout, sc); /* retrieve RT2573 rev. no */ for (ntries = 0; ntries < 1000; ntries++) { @@ -442,19 +442,17 @@ USB_DETACH(rum) if_detach(ifp); usb_rem_task(sc->sc_udev, &sc->sc_task); - timeout_del(&sc->scan_ch); - timeout_del(&sc->amrr_ch); + timeout_del(&sc->scan_to); + timeout_del(&sc->amrr_to); if (sc->amrr_xfer != NULL) { usbd_free_xfer(sc->amrr_xfer); sc->amrr_xfer = NULL; } - if (sc->sc_rx_pipeh != NULL) { usbd_abort_pipe(sc->sc_rx_pipeh); usbd_close_pipe(sc->sc_rx_pipeh); } - if (sc->sc_tx_pipeh != NULL) { usbd_abort_pipe(sc->sc_tx_pipeh); usbd_close_pipe(sc->sc_tx_pipeh); @@ -474,13 +472,12 @@ USB_DETACH(rum) Static int rum_alloc_tx_list(struct rum_softc *sc) { - struct rum_tx_data *data; int i, error; - sc->tx_queued = 0; + sc->tx_cur = sc->tx_queued = 0; - for (i = 0; i < RT2573_TX_LIST_COUNT; i++) { - data = &sc->tx_data[i]; + for (i = 0; i < RUM_TX_LIST_COUNT; i++) { + struct rum_tx_data *data = &sc->tx_data[i]; data->sc = sc; @@ -491,7 +488,6 @@ rum_alloc_tx_list(struct rum_softc *sc) error = ENOMEM; goto fail; } - data->buf = usbd_alloc_buffer(data->xfer, RT2573_TX_DESC_SIZE + IEEE80211_MAX_LEN); if (data->buf == NULL) { @@ -500,7 +496,6 @@ rum_alloc_tx_list(struct rum_softc *sc) error = ENOMEM; goto fail; } - /* clean Tx descriptor */ bzero(data->buf, RT2573_TX_DESC_SIZE); } @@ -514,17 +509,15 @@ fail: rum_free_tx_list(sc); Static void rum_free_tx_list(struct rum_softc *sc) { - struct rum_tx_data *data; int i; - for (i = 0; i < RT2573_TX_LIST_COUNT; i++) { - data = &sc->tx_data[i]; + for (i = 0; i < RUM_TX_LIST_COUNT; i++) { + struct rum_tx_data *data = &sc->tx_data[i]; if (data->xfer != NULL) { usbd_free_xfer(data->xfer); data->xfer = NULL; } - /* * The node has already been freed at that point so don't call * ieee80211_release_node() here. @@ -536,11 +529,10 @@ rum_free_tx_list(struct rum_softc *sc) Static int rum_alloc_rx_list(struct rum_softc *sc) { - struct rum_rx_data *data; int i, error; - for (i = 0; i < RT2573_RX_LIST_COUNT; i++) { - data = &sc->rx_data[i]; + for (i = 0; i < RUM_RX_LIST_COUNT; i++) { + struct rum_rx_data *data = &sc->rx_data[i]; data->sc = sc; @@ -551,7 +543,6 @@ rum_alloc_rx_list(struct rum_softc *sc) error = ENOMEM; goto fail; } - if (usbd_alloc_buffer(data->xfer, MCLBYTES) == NULL) { printf("%s: could not allocate rx buffer\n", USBDEVNAME(sc->sc_dev)); @@ -566,7 +557,6 @@ rum_alloc_rx_list(struct rum_softc *sc) error = ENOMEM; goto fail; } - MCLGET(data->m, M_DONTWAIT); if (!(data->m->m_flags & M_EXT)) { printf("%s: could not allocate rx mbuf cluster\n", @@ -574,7 +564,6 @@ rum_alloc_rx_list(struct rum_softc *sc) error = ENOMEM; goto fail; } - data->buf = mtod(data->m, uint8_t *); } @@ -587,17 +576,15 @@ fail: rum_free_tx_list(sc); Static void rum_free_rx_list(struct rum_softc *sc) { - struct rum_rx_data *data; int i; - for (i = 0; i < RT2573_RX_LIST_COUNT; i++) { - data = &sc->rx_data[i]; + for (i = 0; i < RUM_RX_LIST_COUNT; i++) { + struct rum_rx_data *data = &sc->rx_data[i]; if (data->xfer != NULL) { usbd_free_xfer(data->xfer); data->xfer = NULL; } - if (data->m != NULL) { m_freem(data->m); data->m = NULL; @@ -657,7 +644,7 @@ rum_task(void *arg) case IEEE80211_S_SCAN: rum_set_chan(sc, ic->ic_bss->ni_chan); - timeout_add(&sc->scan_ch, hz / 5); + timeout_add(&sc->scan_to, hz / 5); break; case IEEE80211_S_AUTH: @@ -708,8 +695,8 @@ rum_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) struct rum_softc *sc = ic->ic_if.if_softc; usb_rem_task(sc->sc_udev, &sc->sc_task); - timeout_del(&sc->scan_ch); - timeout_del(&sc->amrr_ch); + timeout_del(&sc->scan_to); + timeout_del(&sc->amrr_to); /* do it in a process context */ sc->sc_state = nstate; @@ -750,8 +737,6 @@ rum_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) s = splnet(); - m_freem(data->m); - data->m = NULL; ieee80211_release_node(ic, data->ni); data->ni = NULL; @@ -774,7 +759,7 @@ rum_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) struct rum_softc *sc = data->sc; struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = &ic->ic_if; - struct rum_rx_desc *desc; + const struct rum_rx_desc *desc; struct ieee80211_frame *wh; struct ieee80211_node *ni; struct mbuf *mnew, *m; @@ -798,7 +783,7 @@ rum_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) goto skip; } - desc = (struct rum_rx_desc *)data->buf; + desc = (const struct rum_rx_desc *)data->buf; if (letoh32(desc->flags) & RT2573_RX_CRC_ERROR) { /* @@ -817,7 +802,6 @@ rum_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) ifp->if_ierrors++; goto skip; } - MCLGET(mnew, M_DONTWAIT); if (!(mnew->m_flags & M_EXT)) { printf("%s: could not allocate rx mbuf cluster\n", @@ -826,7 +810,6 @@ rum_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) ifp->if_ierrors++; goto skip; } - m = data->m; data->m = mnew; data->buf = mtod(data->m, uint8_t *); @@ -882,7 +865,7 @@ rum_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) skip: /* setup a new transfer */ usbd_setup_xfer(xfer, sc->sc_rx_pipeh, data, data->buf, MCLBYTES, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, rum_rxeof); - usbd_transfer(xfer); + (void)usbd_transfer(xfer); } /* @@ -891,7 +874,7 @@ skip: /* setup a new transfer */ */ #if NBPFILTER > 0 Static uint8_t -rum_rxrate(struct rum_rx_desc *desc) +rum_rxrate(const struct rum_rx_desc *desc) { if (letoh32(desc->flags) & RT2573_RX_OFDM) { /* reverse function of rum_plcp_signal */ @@ -921,7 +904,6 @@ rum_rxrate(struct rum_rx_desc *desc) /* * Return the expected ack rate for a frame transmitted at rate `rate'. - * XXX: this should depend on the destination node basic rate set. */ Static int rum_ack_rate(struct ieee80211com *ic, int rate) @@ -1062,7 +1044,7 @@ rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) uint32_t flags = 0; uint16_t dur; usbd_status error; - int xferlen, rate; + int rate, xferlen, pktlen, needrts = 0, needcts = 0; wh = mtod(m0, struct ieee80211_frame *); @@ -1075,30 +1057,102 @@ rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) wh = mtod(m0, struct ieee80211_frame *); } + /* compute actual packet length (including CRC and crypto overhead) */ + pktlen = m0->m_pkthdr.len + IEEE80211_CRC_LEN; + /* pickup a rate */ - if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == - IEEE80211_FC0_TYPE_MGT) { - /* mgmt frames are sent at the lowest available bit-rate */ + if (IEEE80211_IS_MULTICAST(wh->i_addr1) || + ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == + IEEE80211_FC0_TYPE_MGT)) { + /* mgmt/multicast frames are sent at the lowest avail. rate */ rate = ni->ni_rates.rs_rates[0]; - } else { - if (ic->ic_fixed_rate != -1) { - rate = ic->ic_sup_rates[ic->ic_curmode]. - rs_rates[ic->ic_fixed_rate]; - } else - rate = ni->ni_rates.rs_rates[ni->ni_txrate]; - } + } else if (ic->ic_fixed_rate != -1) { + rate = ic->ic_sup_rates[ic->ic_curmode]. + rs_rates[ic->ic_fixed_rate]; + } else + rate = ni->ni_rates.rs_rates[ni->ni_txrate]; rate &= IEEE80211_RATE_VAL; - if (rate == 0) - rate = 2; /* fallback to 1Mbps; should not happen */ - data = &sc->tx_data[0]; + /* check if RTS/CTS or CTS-to-self protection must be used */ + if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { + /* multicast frames are not sent at OFDM rates in 802.11b/g */ + if (pktlen > ic->ic_rtsthreshold) { + needrts = 1; /* RTS/CTS based on frame length */ + } else if ((ic->ic_flags & IEEE80211_F_USEPROT) && + RUM_RATE_IS_OFDM(rate)) { + if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) + needcts = 1; /* CTS-to-self */ + else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) + needrts = 1; /* RTS/CTS */ + } + } + if (needrts || needcts) { + struct mbuf *mprot; + int protrate, ackrate; + uint16_t dur; + + protrate = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? 12 : 2; + ackrate = rum_ack_rate(ic, rate); + + dur = rum_txtime(pktlen, rate, ic->ic_flags) + + rum_txtime(RUM_ACK_SIZE, ackrate, ic->ic_flags) + + 2 * sc->sifs; + if (needrts) { + dur += rum_txtime(RUM_CTS_SIZE, rum_ack_rate(ic, + protrate), ic->ic_flags) + sc->sifs; + mprot = ieee80211_get_rts(ic, wh, dur); + } else { + mprot = ieee80211_get_cts_to_self(ic, dur); + } + if (mprot == NULL) { + printf("%s: could not allocate protection frame\n", + sc->sc_dev.dv_xname); + m_freem(m0); + return ENOBUFS; + } + + data = &sc->tx_data[sc->tx_cur]; + desc = (struct rum_tx_desc *)data->buf; + + /* avoid multiple free() of the same node for each fragment */ + data->ni = ieee80211_ref_node(ni); + + m_copydata(mprot, 0, mprot->m_pkthdr.len, + data->buf + RT2573_TX_DESC_SIZE); + rum_setup_tx_desc(sc, desc, + (needrts ? RT2573_TX_NEED_ACK : 0) | RT2573_TX_MORE_FRAG, + 0, mprot->m_pkthdr.len, protrate); + + /* no roundup necessary here */ + xferlen = RT2573_TX_DESC_SIZE + mprot->m_pkthdr.len; + + /* XXX may want to pass the protection frame to BPF */ + + /* mbuf is no longer needed */ + m_freem(mprot); + + usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf, + xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, + RUM_TX_TIMEOUT, rum_txeof); + error = usbd_transfer(data->xfer); + if (error != 0 && error != USBD_IN_PROGRESS) { + m_freem(m0); + return error; + } + + sc->tx_queued++; + sc->tx_cur = (sc->tx_cur + 1) % RUM_TX_LIST_COUNT; + + flags |= RT2573_TX_LONG_RETRY | RT2573_TX_IFS_SIFS; + } + + data = &sc->tx_data[sc->tx_cur]; desc = (struct rum_tx_desc *)data->buf; - data->m = m0; data->ni = ni; if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { - flags |= RT2573_TX_ACK; + flags |= RT2573_TX_NEED_ACK; dur = rum_txtime(RUM_ACK_SIZE, rum_ack_rate(ic, rate), ic->ic_flags) + sc->sifs; @@ -1147,16 +1201,17 @@ rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) DPRINTFN(10, ("sending frame len=%u rate=%u xfer len=%u\n", m0->m_pkthdr.len + RT2573_TX_DESC_SIZE, rate, xferlen)); + /* mbuf is no longer needed */ + m_freem(m0); + usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf, xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RUM_TX_TIMEOUT, rum_txeof); - error = usbd_transfer(data->xfer); - if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) { - m_freem(m0); + if (error != 0 && error != USBD_IN_PROGRESS) return error; - } sc->tx_queued++; + sc->tx_cur = (sc->tx_cur + 1) % RUM_TX_LIST_COUNT; return 0; } @@ -1179,7 +1234,7 @@ rum_start(struct ifnet *ifp) for (;;) { IF_POLL(&ic->ic_mgtq, m0); if (m0 != NULL) { - if (sc->tx_queued >= RT2573_TX_LIST_COUNT) { + if (sc->tx_queued >= RUM_TX_LIST_COUNT - 1) { ifp->if_flags |= IFF_OACTIVE; break; } @@ -1200,7 +1255,7 @@ rum_start(struct ifnet *ifp) IFQ_POLL(&ifp->if_snd, m0); if (m0 == NULL) break; - if (sc->tx_queued >= RT2573_TX_LIST_COUNT) { + if (sc->tx_queued >= RUM_TX_LIST_COUNT - 1) { ifp->if_flags |= IFF_OACTIVE; break; } @@ -1534,12 +1589,12 @@ rum_set_basicrates(struct rum_softc *sc) if (ic->ic_curmode == IEEE80211_MODE_11B) { /* 11b basic rates: 1, 2Mbps */ rum_write(sc, RT2573_TXRX_CSR5, 0x3); - } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_bss->ni_chan)) { + } else if (ic->ic_curmode == IEEE80211_MODE_11A) { /* 11a basic rates: 6, 12, 24Mbps */ rum_write(sc, RT2573_TXRX_CSR5, 0x150); } else { - /* 11g basic rates: 1, 2, 5.5, 11, 6, 12, 24Mbps */ - rum_write(sc, RT2573_TXRX_CSR5, 0x15f); + /* 11b/g basic rates: 1, 2, 5.5, 11Mbps */ + rum_write(sc, RT2573_TXRX_CSR5, 0xf); } } @@ -1844,11 +1899,10 @@ rum_bbp_init(struct rum_softc *sc) { #define N(a) (sizeof (a) / sizeof ((a)[0])) int i, ntries; - uint8_t val; /* wait for BBP to be ready */ for (ntries = 0; ntries < 100; ntries++) { - val = rum_bbp_read(sc, 0); + const uint8_t val = rum_bbp_read(sc, 0); if (val != 0 && val != 0xff) break; DELAY(1000); @@ -1880,7 +1934,6 @@ rum_init(struct ifnet *ifp) #define N(a) (sizeof (a) / sizeof ((a)[0])) struct rum_softc *sc = ifp->if_softc; struct ieee80211com *ic = &sc->sc_ic; - struct rum_rx_data *data; uint32_t tmp; usbd_status error; int i, ntries; @@ -1946,7 +1999,6 @@ rum_init(struct ifnet *ifp) USBDEVNAME(sc->sc_dev), usbd_errstr(error)); goto fail; } - error = usbd_open_pipe(sc->sc_iface, sc->sc_rx_no, USBD_EXCLUSIVE_USE, &sc->sc_rx_pipeh); if (error != 0) { @@ -1964,7 +2016,6 @@ rum_init(struct ifnet *ifp) USBDEVNAME(sc->sc_dev)); goto fail; } - error = rum_alloc_rx_list(sc); if (error != 0) { printf("%s: could not allocate Rx list\n", @@ -1975,12 +2026,17 @@ rum_init(struct ifnet *ifp) /* * Start up the receive pipe. */ - for (i = 0; i < RT2573_RX_LIST_COUNT; i++) { - data = &sc->rx_data[i]; + for (i = 0; i < RUM_RX_LIST_COUNT; i++) { + struct rum_rx_data *data = &sc->rx_data[i]; usbd_setup_xfer(data->xfer, sc->sc_rx_pipeh, data, data->buf, MCLBYTES, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, rum_rxeof); - usbd_transfer(data->xfer); + error = usbd_transfer(data->xfer); + if (error != 0 && error != USBD_IN_PROGRESS) { + printf("%s: could not queue Rx transfer\n", + USBDEVNAME(sc->sc_dev)); + goto fail; + } } /* update Rx filter */ @@ -2038,7 +2094,6 @@ rum_stop(struct ifnet *ifp, int disable) usbd_close_pipe(sc->sc_rx_pipeh); sc->sc_rx_pipeh = NULL; } - if (sc->sc_tx_pipeh != NULL) { usbd_abort_pipe(sc->sc_tx_pipeh); usbd_close_pipe(sc->sc_tx_pipeh); @@ -2130,7 +2185,7 @@ rum_amrr_start(struct rum_softc *sc, struct ieee80211_node *ni) i--); ni->ni_txrate = i; - timeout_add(&sc->amrr_ch, hz); + timeout_add(&sc->amrr_to, hz); } Static void @@ -2181,7 +2236,7 @@ rum_amrr_update(usbd_xfer_handle xfer, usbd_private_handle priv, ieee80211_amrr_choose(&sc->amrr, sc->sc_ic.ic_bss, &sc->amn); - timeout_add(&sc->amrr_ch, hz); + timeout_add(&sc->amrr_to, hz); } int diff --git a/sys/dev/usb/if_rumreg.h b/sys/dev/usb/if_rumreg.h index d93560b9506..ee10331e431 100644 --- a/sys/dev/usb/if_rumreg.h +++ b/sys/dev/usb/if_rumreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_rumreg.h,v 1.12 2006/08/09 08:21:08 damien Exp $ */ +/* $OpenBSD: if_rumreg.h,v 1.13 2006/11/13 20:06:38 damien Exp $ */ /*- * Copyright (c) 2005, 2006 Damien Bergamini <damien.bergamini@free.fr> @@ -168,7 +168,7 @@ struct rum_tx_desc { #define RT2573_TX_BURST (1 << 0) #define RT2573_TX_VALID (1 << 1) #define RT2573_TX_MORE_FRAG (1 << 2) -#define RT2573_TX_ACK (1 << 3) +#define RT2573_TX_NEED_ACK (1 << 3) #define RT2573_TX_TIMESTAMP (1 << 4) #define RT2573_TX_OFDM (1 << 5) #define RT2573_TX_IFS_SIFS (1 << 6) diff --git a/sys/dev/usb/if_rumvar.h b/sys/dev/usb/if_rumvar.h index a59d4e9a3dc..74ddb2da7cc 100644 --- a/sys/dev/usb/if_rumvar.h +++ b/sys/dev/usb/if_rumvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_rumvar.h,v 1.6 2006/08/18 15:11:12 damien Exp $ */ +/* $OpenBSD: if_rumvar.h,v 1.7 2006/11/13 20:06:38 damien Exp $ */ /*- * Copyright (c) 2005, 2006 Damien Bergamini <damien.bergamini@free.fr> @@ -17,8 +17,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define RT2573_RX_LIST_COUNT 1 -#define RT2573_TX_LIST_COUNT 1 +#define RUM_RX_LIST_COUNT 1 +#define RUM_TX_LIST_COUNT 8 struct rum_rx_radiotap_header { struct ieee80211_radiotap_header wr_ihdr; @@ -58,7 +58,6 @@ struct rum_tx_data { struct rum_softc *sc; usbd_xfer_handle xfer; uint8_t *buf; - struct mbuf *m; struct ieee80211_node *ni; }; @@ -99,12 +98,13 @@ struct rum_softc { struct ieee80211_amrr amrr; struct ieee80211_amrr_node amn; - struct rum_rx_data rx_data[RT2573_RX_LIST_COUNT]; - struct rum_tx_data tx_data[RT2573_TX_LIST_COUNT]; + struct rum_rx_data rx_data[RUM_RX_LIST_COUNT]; + struct rum_tx_data tx_data[RUM_TX_LIST_COUNT]; int tx_queued; + int tx_cur; - struct timeout scan_ch; - struct timeout amrr_ch; + struct timeout scan_to; + struct timeout amrr_to; int sc_tx_timer; diff --git a/sys/dev/usb/if_zyd.c b/sys/dev/usb/if_zyd.c index c9442c6c2ea..87ee6386a2d 100644 --- a/sys/dev/usb/if_zyd.c +++ b/sys/dev/usb/if_zyd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_zyd.c,v 1.35 2006/11/03 19:34:56 damien Exp $ */ +/* $OpenBSD: if_zyd.c,v 1.36 2006/11/13 20:06:38 damien Exp $ */ /*- * Copyright (c) 2006 by Damien Bergamini <damien.bergamini@free.fr> @@ -1088,7 +1088,7 @@ zyd_rf_attach(struct zyd_softc *sc, uint8_t type) rf->init = zyd_al7230B_init; rf->switch_radio = zyd_al7230B_switch_radio; rf->set_channel = zyd_al7230B_set_channel; - rf->width = 24; /* 24-bit RF values */ + rf->width = 24; /* 24-bit RF values */ default: printf("%s: sorry, radio \"%s\" is not supported yet\n", USBDEVNAME(sc->sc_dev), zyd_rf_name(type)); @@ -1639,17 +1639,16 @@ zyd_tx_data(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) } /* pickup a rate */ - if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == - IEEE80211_FC0_TYPE_MGT) { - /* mgmt frames are sent at the lowest available bit-rate */ + if (IEEE80211_IS_MULTICAST(wh->i_addr1) || + ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == + IEEE80211_FC0_TYPE_MGT)) { + /* mgmt/multicast frames are sent at the lowest avail. rate */ rate = ni->ni_rates.rs_rates[0]; - } else { - if (ic->ic_fixed_rate != -1) { - rate = ic->ic_sup_rates[ic->ic_curmode]. - rs_rates[ic->ic_fixed_rate]; - } else - rate = ni->ni_rates.rs_rates[ni->ni_txrate]; - } + } else if (ic->ic_fixed_rate != -1) { + rate = ic->ic_sup_rates[ic->ic_curmode]. + rs_rates[ic->ic_fixed_rate]; + } else + rate = ni->ni_rates.rs_rates[ni->ni_txrate]; rate &= IEEE80211_RATE_VAL; data = &sc->tx_data[0]; @@ -1665,10 +1664,16 @@ zyd_tx_data(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) desc->flags = ZYD_TX_FLAG_BACKOFF; if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { - if (totlen > ic->ic_rtsthreshold || - (ZYD_RATE_IS_OFDM(rate) && - (ic->ic_flags & IEEE80211_F_USEPROT))) + /* multicast frames are not sent at OFDM rates in 802.11b/g */ + if (totlen > ic->ic_rtsthreshold) { desc->flags |= ZYD_TX_FLAG_RTS; + } else if (ZYD_RATE_IS_OFDM(rate) && + (ic->ic_flags & IEEE80211_F_USEPROT)) { + if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) + desc->flags |= ZYD_TX_FLAG_CTS_TO_SELF; + else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) + desc->flags |= ZYD_TX_FLAG_RTS; + } } else desc->flags |= ZYD_TX_FLAG_MULTICAST; @@ -1926,15 +1931,15 @@ zyd_init(struct ifnet *ifp) /* set basic rates */ if (ic->ic_curmode == IEEE80211_MODE_11B) - (void)zyd_write32(sc, ZYD_MAC_BAS_RATE, 0x3); + (void)zyd_write32(sc, ZYD_MAC_BAS_RATE, 0x0003); else if (ic->ic_curmode == IEEE80211_MODE_11A) (void)zyd_write32(sc, ZYD_MAC_BAS_RATE, 0x1500); else /* assumes 802.11b/g */ - (void)zyd_write32(sc, ZYD_MAC_BAS_RATE, 0x150f); + (void)zyd_write32(sc, ZYD_MAC_BAS_RATE, 0x000f); /* set mandatory rates */ if (ic->ic_curmode == IEEE80211_MODE_11B) - (void)zyd_write32(sc, ZYD_MAC_MAN_RATE, 0x0f); + (void)zyd_write32(sc, ZYD_MAC_MAN_RATE, 0x000f); else if (ic->ic_curmode == IEEE80211_MODE_11A) (void)zyd_write32(sc, ZYD_MAC_MAN_RATE, 0x1500); else /* assumes 802.11b/g */ |