diff options
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 */ |