diff options
author | 2006-11-13 20:06:38 +0000 | |
---|---|---|
committer | 2006-11-13 20:06:38 +0000 | |
commit | bc303e9b522b31d160be11e50e51d35b0965c2e6 (patch) | |
tree | e02040d4abfa68bc890072a690e07f020457b71f /sys/dev/usb | |
parent | fix macro abuse leading to stray numbers in the vm display. (diff) | |
download | wireguard-openbsd-bc303e9b522b31d160be11e50e51d35b0965c2e6.tar.xz wireguard-openbsd-bc303e9b522b31d160be11e50e51d35b0965c2e6.zip |
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/usb')
-rw-r--r-- | sys/dev/usb/if_ral.c | 265 | ||||
-rw-r--r-- | sys/dev/usb/if_ralreg.h | 50 | ||||
-rw-r--r-- | sys/dev/usb/if_ralvar.h | 10 | ||||
-rw-r--r-- | sys/dev/usb/if_rum.c | 207 | ||||
-rw-r--r-- | sys/dev/usb/if_rumreg.h | 4 | ||||
-rw-r--r-- | sys/dev/usb/if_rumvar.h | 16 | ||||
-rw-r--r-- | sys/dev/usb/if_zyd.c | 41 |
7 files changed, 306 insertions, 287 deletions
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 */ |