summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ic/rt2560.c298
-rw-r--r--sys/dev/ic/rt2560reg.h49
-rw-r--r--sys/dev/ic/rt2661.c185
-rw-r--r--sys/dev/pci/if_wpi.c41
-rw-r--r--sys/dev/pci/if_wpireg.h3
-rw-r--r--sys/dev/usb/if_ral.c265
-rw-r--r--sys/dev/usb/if_ralreg.h50
-rw-r--r--sys/dev/usb/if_ralvar.h10
-rw-r--r--sys/dev/usb/if_rum.c207
-rw-r--r--sys/dev/usb/if_rumreg.h4
-rw-r--r--sys/dev/usb/if_rumvar.h16
-rw-r--r--sys/dev/usb/if_zyd.c41
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 */