summaryrefslogtreecommitdiff
path: root/sys/dev/ic/rt2560.c
diff options
context:
space:
mode:
authorDamien Bergamini <damien@cvs.openbsd.org>2006-11-13 20:06:39 +0000
committerDamien Bergamini <damien@cvs.openbsd.org>2006-11-13 20:06:39 +0000
commitf815983418862c69f38d2ade274a4785797e276c (patch)
treee83e63c3ae3875de702975496c3bd10651422e08 /sys/dev/ic/rt2560.c
parent5dfdad8c9a03b5917a916a713c679847e5ca3fbb (diff)
first round of commits for proper 11b/g protection support:
- use the newly introduced ieee80211_get_rts() and ieee80211_get_cts_to_self() functions. - use CTS-to-self instead of RTS/CTS to protect OFDM frames in a mixed 11b/g BSS. - make sure multicast frames are sent using CCK modulation. remove support for 5GHz radios in ral(4) RT2560 and ural(4). i'm not aware of any such adapters on the market and 11a code is known to be broken. some cleanup while i'm here.
Diffstat (limited to 'sys/dev/ic/rt2560.c')
-rw-r--r--sys/dev/ic/rt2560.c298
1 files changed, 103 insertions, 195 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);
}
}