Module Name: src Committed By: jmcneill Date: Mon Feb 21 23:50:42 UTC 2011
Modified Files: src/sys/dev/usb: if_rum.c if_rumreg.h if_rumvar.h Log Message: sync driver with openbsd To generate a diff of this commit: cvs rdiff -u -r1.34 -r1.35 src/sys/dev/usb/if_rum.c cvs rdiff -u -r1.3 -r1.4 src/sys/dev/usb/if_rumreg.h cvs rdiff -u -r1.8 -r1.9 src/sys/dev/usb/if_rumvar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/usb/if_rum.c diff -u src/sys/dev/usb/if_rum.c:1.34 src/sys/dev/usb/if_rum.c:1.35 --- src/sys/dev/usb/if_rum.c:1.34 Sun Feb 13 05:51:24 2011 +++ src/sys/dev/usb/if_rum.c Mon Feb 21 23:50:42 2011 @@ -1,5 +1,5 @@ /* $OpenBSD: if_rum.c,v 1.40 2006/09/18 16:20:20 damien Exp $ */ -/* $NetBSD: if_rum.c,v 1.34 2011/02/13 05:51:24 dholland Exp $ */ +/* $NetBSD: if_rum.c,v 1.35 2011/02/21 23:50:42 jmcneill Exp $ */ /*- * Copyright (c) 2005-2007 Damien Bergamini <damien.bergam...@free.fr> @@ -24,7 +24,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_rum.c,v 1.34 2011/02/13 05:51:24 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_rum.c,v 1.35 2011/02/21 23:50:42 jmcneill Exp $"); #include <sys/param.h> @@ -134,71 +134,69 @@ { USB_VENDOR_SURECOM, USB_PRODUCT_SURECOM_RT2573 } }; -Static int rum_attachhook(void *); -Static int rum_alloc_tx_list(struct rum_softc *); -Static void rum_free_tx_list(struct rum_softc *); -Static int rum_alloc_rx_list(struct rum_softc *); -Static void rum_free_rx_list(struct rum_softc *); -Static int rum_media_change(struct ifnet *); -Static void rum_next_scan(void *); -Static void rum_task(void *); -Static int rum_newstate(struct ieee80211com *, +static int rum_attachhook(void *); +static int rum_alloc_tx_list(struct rum_softc *); +static void rum_free_tx_list(struct rum_softc *); +static int rum_alloc_rx_list(struct rum_softc *); +static void rum_free_rx_list(struct rum_softc *); +static int rum_media_change(struct ifnet *); +static void rum_next_scan(void *); +static void rum_task(void *); +static int rum_newstate(struct ieee80211com *, enum ieee80211_state, int); -Static void rum_txeof(usbd_xfer_handle, usbd_private_handle, +static void rum_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -Static void rum_rxeof(usbd_xfer_handle, usbd_private_handle, +static void rum_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -Static uint8_t rum_rxrate(const struct rum_rx_desc *); -Static int rum_ack_rate(struct ieee80211com *, int); -Static uint16_t rum_txtime(int, int, uint32_t); -Static uint8_t rum_plcp_signal(int); -Static void rum_setup_tx_desc(struct rum_softc *, +static uint8_t rum_rxrate(const struct rum_rx_desc *); +static int rum_ack_rate(struct ieee80211com *, int); +static uint16_t rum_txtime(int, int, uint32_t); +static uint8_t rum_plcp_signal(int); +static void rum_setup_tx_desc(struct rum_softc *, struct rum_tx_desc *, uint32_t, uint16_t, int, int); -Static int rum_tx_mgt(struct rum_softc *, struct mbuf *, +static int rum_tx_data(struct rum_softc *, struct mbuf *, struct ieee80211_node *); -Static int rum_tx_data(struct rum_softc *, struct mbuf *, - struct ieee80211_node *); -Static void rum_start(struct ifnet *); -Static void rum_watchdog(struct ifnet *); -Static int rum_ioctl(struct ifnet *, u_long, void *); -Static void rum_eeprom_read(struct rum_softc *, uint16_t, void *, +static void rum_start(struct ifnet *); +static void rum_watchdog(struct ifnet *); +static int rum_ioctl(struct ifnet *, u_long, void *); +static void rum_eeprom_read(struct rum_softc *, uint16_t, void *, int); -Static uint32_t rum_read(struct rum_softc *, uint16_t); -Static void rum_read_multi(struct rum_softc *, uint16_t, void *, +static uint32_t rum_read(struct rum_softc *, uint16_t); +static void rum_read_multi(struct rum_softc *, uint16_t, void *, int); -Static void rum_write(struct rum_softc *, uint16_t, uint32_t); -Static void rum_write_multi(struct rum_softc *, uint16_t, void *, +static void rum_write(struct rum_softc *, uint16_t, uint32_t); +static void rum_write_multi(struct rum_softc *, uint16_t, void *, size_t); -Static void rum_bbp_write(struct rum_softc *, uint8_t, uint8_t); -Static uint8_t rum_bbp_read(struct rum_softc *, uint8_t); -Static void rum_rf_write(struct rum_softc *, uint8_t, uint32_t); -Static void rum_select_antenna(struct rum_softc *); -Static void rum_enable_mrr(struct rum_softc *); -Static void rum_set_txpreamble(struct rum_softc *); -Static void rum_set_basicrates(struct rum_softc *); -Static void rum_select_band(struct rum_softc *, +static void rum_bbp_write(struct rum_softc *, uint8_t, uint8_t); +static uint8_t rum_bbp_read(struct rum_softc *, uint8_t); +static void rum_rf_write(struct rum_softc *, uint8_t, uint32_t); +static void rum_select_antenna(struct rum_softc *); +static void rum_enable_mrr(struct rum_softc *); +static void rum_set_txpreamble(struct rum_softc *); +static void rum_set_basicrates(struct rum_softc *); +static void rum_select_band(struct rum_softc *, struct ieee80211_channel *); -Static void rum_set_chan(struct rum_softc *, +static void rum_set_chan(struct rum_softc *, struct ieee80211_channel *); -Static void rum_enable_tsf_sync(struct rum_softc *); -Static void rum_update_slot(struct rum_softc *); -Static void rum_set_bssid(struct rum_softc *, const uint8_t *); -Static void rum_set_macaddr(struct rum_softc *, const uint8_t *); -Static void rum_update_promisc(struct rum_softc *); -Static const char *rum_get_rf(int); -Static void rum_read_eeprom(struct rum_softc *); -Static int rum_bbp_init(struct rum_softc *); -Static int rum_init(struct ifnet *); -Static void rum_stop(struct ifnet *, int); -Static int rum_load_microcode(struct rum_softc *, const u_char *, +static void rum_enable_tsf_sync(struct rum_softc *); +static void rum_update_slot(struct rum_softc *); +static void rum_set_bssid(struct rum_softc *, const uint8_t *); +static void rum_set_macaddr(struct rum_softc *, const uint8_t *); +static void rum_update_promisc(struct rum_softc *); +static const char *rum_get_rf(int); +static void rum_read_eeprom(struct rum_softc *); +static int rum_bbp_init(struct rum_softc *); +static int rum_init(struct ifnet *); +static void rum_stop(struct ifnet *, int); +static int rum_load_microcode(struct rum_softc *, const u_char *, size_t); -Static int rum_prepare_beacon(struct rum_softc *); -Static void rum_newassoc(struct ieee80211_node *, int); -Static void rum_amrr_start(struct rum_softc *, +static int rum_prepare_beacon(struct rum_softc *); +static void rum_newassoc(struct ieee80211_node *, int); +static void rum_amrr_start(struct rum_softc *, struct ieee80211_node *); -Static void rum_amrr_timeout(void *); -Static void rum_amrr_update(usbd_xfer_handle, usbd_private_handle, +static void rum_amrr_timeout(void *); +static void rum_amrr_update(usbd_xfer_handle, usbd_private_handle, usbd_status status); /* @@ -236,15 +234,15 @@ RT2573_RF5225 }; -int rum_match(device_t, cfdata_t, void *); -void rum_attach(device_t, device_t, void *); -int rum_detach(device_t, int); -int rum_activate(device_t, enum devact); +static int rum_match(device_t, cfdata_t, void *); +static void rum_attach(device_t, device_t, void *); +static int rum_detach(device_t, int); +static int rum_activate(device_t, enum devact); extern struct cfdriver rum_cd; CFATTACH_DECL_NEW(rum, sizeof(struct rum_softc), rum_match, rum_attach, rum_detach, rum_activate); -int +static int rum_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; @@ -253,7 +251,7 @@ UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } -Static int +static int rum_attachhook(void *xsc) { struct rum_softc *sc = xsc; @@ -298,7 +296,7 @@ return 0; } -void +static void rum_attach(device_t parent, device_t self, void *aux) { struct rum_softc *sc = device_private(self); @@ -482,7 +480,7 @@ return; } -int +static int rum_detach(device_t self, int flags) { struct rum_softc *sc = device_private(self); @@ -526,13 +524,13 @@ return 0; } -Static int +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 < RUM_TX_LIST_COUNT; i++) { data = &sc->tx_data[i]; @@ -548,7 +546,7 @@ } data->buf = usbd_alloc_buffer(data->xfer, - RT2573_TX_DESC_SIZE + MCLBYTES); + RT2573_TX_DESC_SIZE + IEEE80211_MAX_LEN); if (data->buf == NULL) { printf("%s: could not allocate tx buffer\n", device_xname(sc->sc_dev)); @@ -566,7 +564,7 @@ return error; } -Static void +static void rum_free_tx_list(struct rum_softc *sc) { struct rum_tx_data *data; @@ -587,7 +585,7 @@ } } -Static int +static int rum_alloc_rx_list(struct rum_softc *sc) { struct rum_rx_data *data; @@ -638,7 +636,7 @@ return error; } -Static void +static void rum_free_rx_list(struct rum_softc *sc) { struct rum_rx_data *data; @@ -659,7 +657,7 @@ } } -Static int +static int rum_media_change(struct ifnet *ifp) { int error; @@ -678,17 +676,20 @@ * This function is called periodically (every 200ms) during scanning to * switch from one channel to another. */ -Static void +static void rum_next_scan(void *arg) { struct rum_softc *sc = arg; struct ieee80211com *ic = &sc->sc_ic; + int s; + s = splnet(); if (ic->ic_state == IEEE80211_S_SCAN) ieee80211_next_scan(ic); + splx(s); } -Static void +static void rum_task(void *arg) { struct rum_softc *sc = arg; @@ -753,10 +754,10 @@ break; } - sc->sc_newstate(ic, sc->sc_state, -1); + sc->sc_newstate(ic, sc->sc_state, sc->sc_arg); } -Static int +static int rum_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) { struct rum_softc *sc = ic->ic_ifp->if_softc; @@ -767,6 +768,7 @@ /* do it in a process context */ sc->sc_state = nstate; + sc->sc_arg = arg; usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER); return 0; @@ -778,7 +780,7 @@ #define RUM_ACK_SIZE 14 /* 10 + 4(FCS) */ #define RUM_CTS_SIZE 14 /* 10 + 4(FCS) */ -Static void +static void rum_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) { struct rum_tx_data *data = priv; @@ -817,7 +819,7 @@ splx(s); } -Static void +static void rum_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) { struct rum_rx_data *data = priv; @@ -924,7 +926,7 @@ * This function is only used by the Rx radiotap code. It returns the rate at * which a given frame was received. */ -Static uint8_t +static uint8_t rum_rxrate(const struct rum_rx_desc *desc) { if (le32toh(desc->flags) & RT2573_RX_OFDM) { @@ -956,7 +958,7 @@ * 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 +static int rum_ack_rate(struct ieee80211com *ic, int rate) { switch (rate) { @@ -991,7 +993,7 @@ * The function automatically determines the operating mode depending on the * given rate. `flags' indicates whether short preamble is in use or not. */ -Static uint16_t +static uint16_t rum_txtime(int len, int rate, uint32_t flags) { uint16_t txtime; @@ -1011,7 +1013,7 @@ return txtime; } -Static uint8_t +static uint8_t rum_plcp_signal(int rate) { switch (rate) { @@ -1036,7 +1038,7 @@ } } -Static void +static void rum_setup_tx_desc(struct rum_softc *sc, struct rum_tx_desc *desc, uint32_t flags, uint16_t xflags, int len, int rate) { @@ -1084,8 +1086,8 @@ #define RUM_TX_TIMEOUT 5000 -Static int -rum_tx_mgt(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) +static int +rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) { struct ieee80211com *ic = &sc->sc_ic; struct rum_tx_desc *desc; @@ -1095,15 +1097,7 @@ uint32_t flags = 0; uint16_t dur; usbd_status error; - int xferlen, rate; - - data = &sc->tx_data[0]; - desc = (struct rum_tx_desc *)data->buf; - - rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2; - - data->m = m0; - data->ni = ni; + int rate, xferlen, pktlen, needrts = 0, needcts = 0; wh = mtod(m0, struct ieee80211_frame *); @@ -1113,102 +1107,102 @@ m_freem(m0); return ENOBUFS; } - } - - wh = mtod(m0, struct ieee80211_frame *); - - if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { - flags |= RT2573_TX_NEED_ACK; - - dur = rum_txtime(RUM_ACK_SIZE, rum_ack_rate(ic, rate), - ic->ic_flags) + sc->sifs; - *(uint16_t *)wh->i_dur = htole16(dur); - - /* tell hardware to set timestamp in probe responses */ - if ((wh->i_fc[0] & - (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == - (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP)) - flags |= RT2573_TX_TIMESTAMP; - } - - if (sc->sc_drvbpf != NULL) { - struct rum_tx_radiotap_header *tap = &sc->sc_txtap; - - tap->wt_flags = 0; - tap->wt_rate = rate; - tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); - tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); - tap->wt_antenna = sc->tx_ant; - bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0); + /* packet header may have moved, reset our local pointer */ + wh = mtod(m0, struct ieee80211_frame *); } - m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + RT2573_TX_DESC_SIZE); - rum_setup_tx_desc(sc, desc, flags, 0, m0->m_pkthdr.len, rate); + /* compute actual packet length (including CRC and crypto overhead) */ + pktlen = m0->m_pkthdr.len + IEEE80211_CRC_LEN; - /* align end on a 4-bytes boundary */ - xferlen = (RT2573_TX_DESC_SIZE + m0->m_pkthdr.len + 3) & ~3; - - /* - * No space left in the last URB to store the extra 4 bytes, force - * sending of another URB. - */ - if ((xferlen % 64) == 0) - xferlen += 4; - - DPRINTFN(10, ("sending msg frame len=%zu rate=%u xfer len=%u\n", - (size_t)m0->m_pkthdr.len + RT2573_TX_DESC_SIZE, - rate, xferlen)); + /* 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 != IEEE80211_FIXED_RATE_NONE) { + rate = ic->ic_bss->ni_rates.rs_rates[ic->ic_fixed_rate]; + } else + rate = ni->ni_rates.rs_rates[ni->ni_txrate]; + if (rate == 0) + rate = 2; /* XXX should not happen */ + rate &= IEEE80211_RATE_VAL; - 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); + /* 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; + + 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) { + aprint_error_dev(sc->sc_dev, + "couldn't allocate protection frame\n"); + m_freem(m0); + return ENOBUFS; + } - error = usbd_transfer(data->xfer); - if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) { - m_freem(m0); - return error; - } + data = &sc->tx_data[sc->tx_cur]; + desc = (struct rum_tx_desc *)data->buf; - sc->tx_queued++; + /* avoid multiple free() of the same node for each fragment */ + data->ni = ieee80211_ref_node(ni); - return 0; -} + 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); -Static int -rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) -{ - struct ieee80211com *ic = &sc->sc_ic; - struct rum_tx_desc *desc; - struct rum_tx_data *data; - struct ieee80211_frame *wh; - struct ieee80211_key *k; - uint32_t flags = 0; - uint16_t dur; - usbd_status error; - int xferlen, rate; + /* no roundup necessary here */ + xferlen = RT2573_TX_DESC_SIZE + mprot->m_pkthdr.len; - wh = mtod(m0, struct ieee80211_frame *); + /* XXX may want to pass the protection frame to BPF */ - if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) - rate = ic->ic_bss->ni_rates.rs_rates[ic->ic_fixed_rate]; - else - rate = ni->ni_rates.rs_rates[ni->ni_txrate]; - if (rate == 0) - rate = 2; /* XXX should not happen */ - rate &= IEEE80211_RATE_VAL; + /* mbuf is no longer needed */ + m_freem(mprot); - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - k = ieee80211_crypto_encap(ic, ni, m0); - if (k == NULL) { + 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); - return ENOBUFS; + return error; } - /* packet header may have moved, reset our local pointer */ - wh = mtod(m0, struct ieee80211_frame *); + 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[0]; + data = &sc->tx_data[sc->tx_cur]; desc = (struct rum_tx_desc *)data->buf; data->ni = ni; @@ -1219,6 +1213,12 @@ dur = rum_txtime(RUM_ACK_SIZE, rum_ack_rate(ic, rate), ic->ic_flags) + sc->sifs; *(uint16_t *)wh->i_dur = htole16(dur); + + /* tell hardware to set timestamp in probe responses */ + if ((wh->i_fc[0] & + (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == + (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP)) + flags |= RT2573_TX_TIMESTAMP; } if (sc->sc_drvbpf != NULL) { @@ -1255,17 +1255,17 @@ 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) return error; sc->tx_queued++; + sc->tx_cur = (sc->tx_cur + 1) % RUM_TX_LIST_COUNT; return 0; } -Static void +static void rum_start(struct ifnet *ifp) { struct rum_softc *sc = ifp->if_softc; @@ -1274,10 +1274,13 @@ struct ieee80211_node *ni; struct mbuf *m0; + if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) + return; + for (;;) { IF_POLL(&ic->ic_mgtq, m0); if (m0 != NULL) { - if (sc->tx_queued >= RUM_TX_LIST_COUNT) { + if (sc->tx_queued >= RUM_TX_LIST_COUNT - 1) { ifp->if_flags |= IFF_OACTIVE; break; } @@ -1286,7 +1289,7 @@ ni = (struct ieee80211_node *)m0->m_pkthdr.rcvif; m0->m_pkthdr.rcvif = NULL; bpf_mtap3(ic->ic_rawbpf, m0); - if (rum_tx_mgt(sc, m0, ni) != 0) + if (rum_tx_data(sc, m0, ni) != 0) break; } else { @@ -1295,7 +1298,7 @@ IFQ_POLL(&ifp->if_snd, m0); if (m0 == NULL) break; - if (sc->tx_queued >= RUM_TX_LIST_COUNT) { + if (sc->tx_queued >= RUM_TX_LIST_COUNT - 1) { ifp->if_flags |= IFF_OACTIVE; break; } @@ -1329,7 +1332,7 @@ } } -Static void +static void rum_watchdog(struct ifnet *ifp) { struct rum_softc *sc = ifp->if_softc; @@ -1350,7 +1353,7 @@ ieee80211_watchdog(ic); } -Static int +static int rum_ioctl(struct ifnet *ifp, u_long cmd, void *data) { struct rum_softc *sc = ifp->if_softc; @@ -1395,7 +1398,7 @@ return error; } -Static void +static void rum_eeprom_read(struct rum_softc *sc, uint16_t addr, void *buf, int len) { usb_device_request_t req; @@ -1414,7 +1417,7 @@ } } -Static uint32_t +static uint32_t rum_read(struct rum_softc *sc, uint16_t reg) { uint32_t val; @@ -1424,7 +1427,7 @@ return le32toh(val); } -Static void +static void rum_read_multi(struct rum_softc *sc, uint16_t reg, void *buf, int len) { usb_device_request_t req; @@ -1443,7 +1446,7 @@ } } -Static void +static void rum_write(struct rum_softc *sc, uint16_t reg, uint32_t val) { uint32_t tmp = htole32(val); @@ -1451,7 +1454,7 @@ rum_write_multi(sc, reg, &tmp, sizeof tmp); } -Static void +static void rum_write_multi(struct rum_softc *sc, uint16_t reg, void *buf, size_t len) { usb_device_request_t req; @@ -1470,7 +1473,7 @@ } } -Static void +static void rum_bbp_write(struct rum_softc *sc, uint8_t reg, uint8_t val) { uint32_t tmp; @@ -1489,7 +1492,7 @@ rum_write(sc, RT2573_PHY_CSR3, tmp); } -Static uint8_t +static uint8_t rum_bbp_read(struct rum_softc *sc, uint8_t reg) { uint32_t val; @@ -1518,7 +1521,7 @@ return 0; } -Static void +static void rum_rf_write(struct rum_softc *sc, uint8_t reg, uint32_t val) { uint32_t tmp; @@ -1543,7 +1546,7 @@ DPRINTFN(15, ("RF R[%u] <- 0x%05x\n", reg & 3, val & 0xfffff)); } -Static void +static void rum_select_antenna(struct rum_softc *sc) { uint8_t bbp4, bbp77; @@ -1568,7 +1571,7 @@ * Enable multi-rate retries for frames sent at OFDM rates. * In 802.11b/g mode, allow fallback to CCK rates. */ -Static void +static void rum_enable_mrr(struct rum_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; @@ -1584,7 +1587,7 @@ rum_write(sc, RT2573_TXRX_CSR4, tmp); } -Static void +static void rum_set_txpreamble(struct rum_softc *sc) { uint32_t tmp; @@ -1598,7 +1601,7 @@ rum_write(sc, RT2573_TXRX_CSR4, tmp); } -Static void +static void rum_set_basicrates(struct rum_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; @@ -1620,7 +1623,7 @@ * Reprogram MAC/BBP to switch to a new band. Values taken from the reference * driver. */ -Static void +static void rum_select_band(struct rum_softc *sc, struct ieee80211_channel *c) { uint8_t bbp17, bbp35, bbp96, bbp97, bbp98, bbp104; @@ -1666,7 +1669,7 @@ sc->sifs = IEEE80211_IS_CHAN_5GHZ(c) ? 16 : 10; } -Static void +static void rum_set_chan(struct rum_softc *sc, struct ieee80211_channel *c) { struct ieee80211com *ic = &sc->sc_ic; @@ -1739,7 +1742,7 @@ * Enable TSF synchronization and tell h/w to start sending beacons for IBSS * and HostAP operating modes. */ -Static void +static void rum_enable_tsf_sync(struct rum_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; @@ -1767,7 +1770,7 @@ rum_write(sc, RT2573_TXRX_CSR9, tmp); } -Static void +static void rum_update_slot(struct rum_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; @@ -1783,7 +1786,7 @@ DPRINTF(("setting slot time to %uus\n", slottime)); } -Static void +static void rum_set_bssid(struct rum_softc *sc, const uint8_t *bssid) { uint32_t tmp; @@ -1795,7 +1798,7 @@ rum_write(sc, RT2573_MAC_CSR5, tmp); } -Static void +static void rum_set_macaddr(struct rum_softc *sc, const uint8_t *addr) { uint32_t tmp; @@ -1807,7 +1810,7 @@ rum_write(sc, RT2573_MAC_CSR3, tmp); } -Static void +static void rum_update_promisc(struct rum_softc *sc) { struct ifnet *ifp = sc->sc_ic.ic_ifp; @@ -1825,7 +1828,7 @@ "entering" : "leaving")); } -Static const char * +static const char * rum_get_rf(int rev) { switch (rev) { @@ -1837,7 +1840,7 @@ } } -Static void +static void rum_read_eeprom(struct rum_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; @@ -1912,7 +1915,7 @@ #endif } -Static int +static int rum_bbp_init(struct rum_softc *sc) { #define N(a) (sizeof (a) / sizeof ((a)[0])) @@ -1947,7 +1950,7 @@ #undef N } -Static int +static int rum_init(struct ifnet *ifp) { #define N(a) (sizeof (a) / sizeof ((a)[0])) @@ -2095,7 +2098,7 @@ #undef N } -Static void +static void rum_stop(struct ifnet *ifp, int disable) { struct rum_softc *sc = ifp->if_softc; @@ -2116,6 +2119,11 @@ rum_write(sc, RT2573_MAC_CSR1, 3); rum_write(sc, RT2573_MAC_CSR1, 0); + 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); @@ -2132,7 +2140,7 @@ rum_free_tx_list(sc); } -Static int +static int rum_load_microcode(struct rum_softc *sc, const u_char *ucode, size_t size) { usb_device_request_t req; @@ -2157,7 +2165,7 @@ return error; } -Static int +static int rum_prepare_beacon(struct rum_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; @@ -2190,14 +2198,14 @@ return 0; } -Static void +static void rum_newassoc(struct ieee80211_node *ni, int isnew) { /* start with lowest Tx rate */ ni->ni_txrate = 0; } -Static void +static void rum_amrr_start(struct rum_softc *sc, struct ieee80211_node *ni) { int i; @@ -2216,7 +2224,7 @@ callout_reset(&sc->sc_amrr_ch, hz, rum_amrr_timeout, sc); } -Static void +static void rum_amrr_timeout(void *arg) { struct rum_softc *sc = arg; @@ -2237,7 +2245,7 @@ (void)usbd_transfer(sc->amrr_xfer); } -Static void +static void rum_amrr_update(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) { @@ -2267,7 +2275,7 @@ callout_reset(&sc->sc_amrr_ch, hz, rum_amrr_timeout, sc); } -int +static int rum_activate(device_t self, enum devact act) { switch (act) { @@ -2275,6 +2283,6 @@ /*if_deactivate(&sc->sc_ic.ic_if);*/ return 0; default: - return EOPNOTSUPP; + return 0; } } Index: src/sys/dev/usb/if_rumreg.h diff -u src/sys/dev/usb/if_rumreg.h:1.3 src/sys/dev/usb/if_rumreg.h:1.4 --- src/sys/dev/usb/if_rumreg.h:1.3 Fri May 29 18:49:21 2009 +++ src/sys/dev/usb/if_rumreg.h Mon Feb 21 23:50:42 2011 @@ -1,5 +1,5 @@ -/* $NetBSD: if_rumreg.h,v 1.3 2009/05/29 18:49:21 plunky Exp $ */ -/* $OpenBSD: if_rumreg.h,v 1.13 2006/11/13 20:06:38 damien Exp $ */ +/* $NetBSD: if_rumreg.h,v 1.4 2011/02/21 23:50:42 jmcneill Exp $ */ +/* $OpenBSD: if_rumreg.h,v 1.14 2009/08/10 18:04:56 damien Exp $ */ /*- * Copyright (c) 2005, 2006 Damien Bergamini <damien.bergam...@free.fr> @@ -40,6 +40,9 @@ #define RT2573_CWMAX_CSR 0x0408 #define RT2573_MCU_CODE_BASE 0x0800 #define RT2573_HW_BEACON_BASE0 0x2400 +#define RT2573_HW_BEACON_BASE1 0x2500 +#define RT2573_HW_BEACON_BASE2 0x2600 +#define RT2573_HW_BEACON_BASE3 0x2700 #define RT2573_MAC_CSR0 0x3000 #define RT2573_MAC_CSR1 0x3004 #define RT2573_MAC_CSR2 0x3008 @@ -237,28 +240,32 @@ * Default values for MAC registers; values taken from the reference driver. */ #define RT2573_DEF_MAC \ - { RT2573_TXRX_CSR0, 0x025fb032 }, \ - { RT2573_TXRX_CSR1, 0x9eaa9eaf }, \ - { RT2573_TXRX_CSR2, 0x8a8b8c8d }, \ - { RT2573_TXRX_CSR3, 0x00858687 }, \ - { RT2573_TXRX_CSR7, 0x2e31353b }, \ - { RT2573_TXRX_CSR8, 0x2a2a2a2c }, \ - { RT2573_TXRX_CSR15, 0x0000000f }, \ - { RT2573_MAC_CSR6, 0x00000fff }, \ - { RT2573_MAC_CSR8, 0x016c030a }, \ - { RT2573_MAC_CSR10, 0x00000718 }, \ - { RT2573_MAC_CSR12, 0x00000004 }, \ - { RT2573_MAC_CSR13, 0x00007f00 }, \ - { RT2573_SEC_CSR0, 0x00000000 }, \ - { RT2573_SEC_CSR1, 0x00000000 }, \ - { RT2573_SEC_CSR5, 0x00000000 }, \ - { RT2573_PHY_CSR1, 0x000023b0 }, \ - { RT2573_PHY_CSR5, 0x00040a06 }, \ - { RT2573_PHY_CSR6, 0x00080606 }, \ - { RT2573_PHY_CSR7, 0x00000408 }, \ - { RT2573_AIFSN_CSR, 0x00002273 }, \ - { RT2573_CWMIN_CSR, 0x00002344 }, \ - { RT2573_CWMAX_CSR, 0x000034aa } + { RT2573_TXRX_CSR0, 0x025fb032 }, \ + { RT2573_TXRX_CSR1, 0x9eaa9eaf }, \ + { RT2573_TXRX_CSR2, 0x8a8b8c8d }, \ + { RT2573_TXRX_CSR3, 0x00858687 }, \ + { RT2573_TXRX_CSR7, 0x2e31353b }, \ + { RT2573_TXRX_CSR8, 0x2a2a2a2c }, \ + { RT2573_TXRX_CSR15, 0x0000000f }, \ + { RT2573_MAC_CSR6, 0x00000fff }, \ + { RT2573_MAC_CSR8, 0x016c030a }, \ + { RT2573_MAC_CSR10, 0x00000718 }, \ + { RT2573_MAC_CSR12, 0x00000004 }, \ + { RT2573_MAC_CSR13, 0x00007f00 }, \ + { RT2573_SEC_CSR0, 0x00000000 }, \ + { RT2573_SEC_CSR1, 0x00000000 }, \ + { RT2573_SEC_CSR5, 0x00000000 }, \ + { RT2573_PHY_CSR1, 0x000023b0 }, \ + { RT2573_PHY_CSR5, 0x00040a06 }, \ + { RT2573_PHY_CSR6, 0x00080606 }, \ + { RT2573_PHY_CSR7, 0x00000408 }, \ + { RT2573_AIFSN_CSR, 0x00002273 }, \ + { RT2573_CWMIN_CSR, 0x00002344 }, \ + { RT2573_CWMAX_CSR, 0x000034aa }, \ + { RT2573_HW_BEACON_BASE0, 0x00000000 }, \ + { RT2573_HW_BEACON_BASE1, 0x00000000 }, \ + { RT2573_HW_BEACON_BASE2, 0x00000000 }, \ + { RT2573_HW_BEACON_BASE3, 0x00000000 } /* * Default values for BBP registers; values taken from the reference driver. Index: src/sys/dev/usb/if_rumvar.h diff -u src/sys/dev/usb/if_rumvar.h:1.8 src/sys/dev/usb/if_rumvar.h:1.9 --- src/sys/dev/usb/if_rumvar.h:1.8 Wed Nov 3 22:30:50 2010 +++ src/sys/dev/usb/if_rumvar.h Mon Feb 21 23:50:42 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: if_rumvar.h,v 1.8 2010/11/03 22:30:50 dyoung Exp $ */ +/* $NetBSD: if_rumvar.h,v 1.9 2011/02/21 23:50:42 jmcneill Exp $ */ /* $OpenBSD: if_rumvar.h,v 1.7 2006/11/13 20:06:38 damien Exp $ */ /*- @@ -19,7 +19,7 @@ */ #define RUM_RX_LIST_COUNT 1 -#define RUM_TX_LIST_COUNT 1 +#define RUM_TX_LIST_COUNT 8 struct rum_rx_radiotap_header { struct ieee80211_radiotap_header wr_ihdr; @@ -98,6 +98,7 @@ usbd_pipe_handle sc_tx_pipeh; enum ieee80211_state sc_state; + int sc_arg; struct usb_task sc_task; struct ieee80211_amrr amrr; @@ -106,6 +107,7 @@ 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 ieee80211_beacon_offsets sc_bo;