Date: Tue, 24 Feb 2009 18:17:35 GMT From: Andrew Thompson <thompsa@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 158215 for review Message-ID: <200902241817.n1OIHZpx010257@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=158215 Change 158215 by thompsa@thompsa_burger on 2009/02/24 18:17:28 Restore the last of the unmerged P4 changes. Affected files ... .. //depot/projects/usb/src/sys/dev/usb/wlan/if_rum.c#2 edit .. //depot/projects/usb/src/sys/dev/usb/wlan/if_rumfw.h#2 edit .. //depot/projects/usb/src/sys/dev/usb/wlan/if_rumreg.h#2 edit .. //depot/projects/usb/src/sys/dev/usb/wlan/if_rumvar.h#2 edit .. //depot/projects/usb/src/sys/dev/usb/wlan/if_ural.c#2 edit .. //depot/projects/usb/src/sys/dev/usb/wlan/if_uralreg.h#2 edit .. //depot/projects/usb/src/sys/dev/usb/wlan/if_uralvar.h#2 edit .. //depot/projects/usb/src/sys/dev/usb/wlan/if_zyd.c#2 edit .. //depot/projects/usb/src/sys/dev/usb/wlan/if_zydfw.h#2 edit .. //depot/projects/usb/src/sys/dev/usb/wlan/if_zydreg.h#2 edit .. //depot/projects/usb/src/sys/dev/usb/wlan/usb_wlan.h#2 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb/wlan/if_rum.c#2 (text+ko) ==== @@ -1,9 +1,9 @@ -/* $FreeBSD: src/sys/dev/usb/wlan/if_rum.c,v 1.3 2009/02/24 17:15:29 ed Exp $ */ +/* $FreeBSD: src/sys/dev/usb2/wlan/if_rum2.c,v 1.12 2009/02/09 22:18:11 thompsa Exp $ */ /*- * Copyright (c) 2005-2007 Damien Bergamini <damien.bergamini@free.fr> * Copyright (c) 2006 Niall O'Higgins <niallo@openbsd.org> - * Copyright (c) 2007-2008 Hans Petter Selasky <hselasky@FreeBSD.org> + * Copyright (c) 2007-2008 Hans Petter Selasky <hselasky@freebsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -19,32 +19,32 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/dev/usb/wlan/if_rum.c,v 1.3 2009/02/24 17:15:29 ed Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/usb2/wlan/if_rum2.c,v 1.12 2009/02/09 22:18:11 thompsa Exp $"); /*- * Ralink Technology RT2501USB/RT2601USB chipset driver * http://www.ralinktech.com.tw/ */ -#include "usbdevs.h" -#include <dev/usb/usb.h> -#include <dev/usb/usb_mfunc.h> -#include <dev/usb/usb_error.h> +#include <dev/usb2/include/usb2_devid.h> +#include <dev/usb2/include/usb2_standard.h> +#include <dev/usb2/include/usb2_mfunc.h> +#include <dev/usb2/include/usb2_error.h> #define USB_DEBUG_VAR rum_debug -#include <dev/usb/usb_core.h> -#include <dev/usb/usb_lookup.h> -#include <dev/usb/usb_process.h> -#include <dev/usb/usb_debug.h> -#include <dev/usb/usb_request.h> -#include <dev/usb/usb_busdma.h> -#include <dev/usb/usb_util.h> +#include <dev/usb2/core/usb2_core.h> +#include <dev/usb2/core/usb2_lookup.h> +#include <dev/usb2/core/usb2_process.h> +#include <dev/usb2/core/usb2_debug.h> +#include <dev/usb2/core/usb2_request.h> +#include <dev/usb2/core/usb2_busdma.h> +#include <dev/usb2/core/usb2_util.h> -#include <dev/usb/wlan/usb_wlan.h> -#include <dev/usb/wlan/if_rumreg.h> -#include <dev/usb/wlan/if_rumvar.h> -#include <dev/usb/wlan/if_rumfw.h> +#include <dev/usb2/wlan/usb2_wlan.h> +#include <dev/usb2/wlan/if_rumreg.h> +#include <dev/usb2/wlan/if_rumvar.h> +#include <dev/usb2/wlan/if_rumfw.h> #if USB_DEBUG static int rum_debug = 0; @@ -54,9 +54,6 @@ "Debug level"); #endif -#define rum_do_request(sc,req,data) \ - usb2_do_request_proc((sc)->sc_udev, &(sc)->sc_tq, req, data, 0, NULL, 5000) - static const struct usb2_device_id rum_devs[] = { { USB_VP(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_HWU54DM) }, { USB_VP(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_2) }, @@ -109,7 +106,8 @@ MODULE_DEPEND(rum, wlan, 1, 1, 1); MODULE_DEPEND(rum, wlan_amrr, 1, 1, 1); -MODULE_DEPEND(rum, usb, 1, 1, 1); +MODULE_DEPEND(rum, usb2_wlan, 1, 1, 1); +MODULE_DEPEND(rum, usb2_core, 1, 1, 1); static device_probe_t rum_match; static device_attach_t rum_attach; @@ -118,6 +116,7 @@ static usb2_callback_t rum_bulk_read_callback; static usb2_callback_t rum_bulk_write_callback; +static usb2_proc_callback_t rum_command_wrapper; static usb2_proc_callback_t rum_attach_post; static usb2_proc_callback_t rum_task; static usb2_proc_callback_t rum_scantask; @@ -125,7 +124,10 @@ static usb2_proc_callback_t rum_amrr_task; static usb2_proc_callback_t rum_init_task; static usb2_proc_callback_t rum_stop_task; +static usb2_proc_callback_t rum_flush_task; +static usb2_error_t rum_do_request(struct rum_softc *sc, + struct usb2_device_request *req, void *data); static struct ieee80211vap *rum_vap_create(struct ieee80211com *, const char name[IFNAMSIZ], int unit, int opmode, int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], @@ -153,8 +155,8 @@ 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 usb2_error_t rum_write(struct rum_softc *, uint16_t, uint32_t); +static usb2_error_t 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); @@ -171,11 +173,13 @@ static void rum_update_slot(struct ifnet *); 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_mcast(struct ifnet *); +static void rum_update_promisc(struct ifnet *); static const char *rum_get_rf(int); static void rum_read_eeprom(struct rum_softc *); static int rum_bbp_init(struct rum_softc *); static void rum_init(void *); -static int rum_load_microcode(struct rum_softc *, const u_char *, +static void rum_load_microcode(struct rum_softc *, const uint8_t *, size_t); static int rum_prepare_beacon(struct rum_softc *, struct ieee80211vap *); @@ -191,7 +195,7 @@ static void rum_amrr_start(struct rum_softc *, struct ieee80211_node *); static void rum_amrr_timeout(void *); -static int rum_pause(struct rum_softc *, int); +static uint8_t rum_pause(struct rum_softc *, unsigned int); static void rum_queue_command(struct rum_softc *, usb2_proc_callback_t *, struct usb2_proc_msg *, struct usb2_proc_msg *); @@ -405,6 +409,8 @@ mtx_init(&sc->sc_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK, MTX_DEF); + cv_init(&sc->sc_cmd_cv, "wtxdone"); + iface_index = RT2573_IFACE_INDEX; error = usb2_transfer_setup(uaa->device, &iface_index, sc->sc_xfer, rum_config, RUM_N_TRANSFER, sc, &sc->sc_mtx); @@ -441,12 +447,11 @@ struct ifnet *ifp; struct ieee80211com *ic; unsigned int ntries; - int error; uint32_t tmp; uint8_t bands; /* retrieve RT2573 rev. no */ - for (ntries = 0; ntries < 100; ntries++) { + for (ntries = 0; ntries != 100; ntries++) { if ((tmp = rum_read(sc, RT2573_MAC_CSR0)) != 0) break; if (rum_pause(sc, hz / 100)) @@ -463,12 +468,12 @@ device_printf(sc->sc_dev, "MAC/BBP RT2573 (rev 0x%05x), RF %s\n", tmp, rum_get_rf(sc->rf_rev)); - error = rum_load_microcode(sc, rt2573_ucode, sizeof(rt2573_ucode)); - if (error != 0) { - RUM_UNLOCK(sc); - device_printf(sc->sc_dev, "could not load 8051 microcode\n"); + rum_load_microcode(sc, rt2573_ucode, sizeof(rt2573_ucode)); + + /* XXX WLAN race --hps */ + if (usb2_proc_is_gone(&sc->sc_tq)) return; - } + RUM_UNLOCK(sc); ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); @@ -514,6 +519,8 @@ ieee80211_init_channels(ic, NULL, &bands); ieee80211_ifattach(ic); + ic->ic_update_mcast = rum_update_mcast; + ic->ic_update_promisc = rum_update_promisc; ic->ic_newassoc = rum_newassoc; ic->ic_raw_xmit = rum_raw_xmit; ic->ic_node_alloc = rum_node_alloc; @@ -569,11 +576,31 @@ if_free(ifp); } + cv_destroy(&sc->sc_cmd_cv); + mtx_destroy(&sc->sc_mtx); return (0); } +static usb2_error_t +rum_do_request(struct rum_softc *sc, + struct usb2_device_request *req, void *data) +{ + usb2_error_t err; +retry: + err = usb2_do_request_proc(sc->sc_udev, &sc->sc_tq, + req, data, 0, NULL, 250 /* ms */); + + if (err) { + DPRINTFN(1, "Control request failed, " + "%s! (ignored)\n", usb2_errstr(err)); + if ((sc->sc_ifp != NULL) && (!rum_pause(sc, hz / 100))) + goto retry; + } + return (err); +} + static struct ieee80211vap * rum_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, int opmode, int flags, @@ -613,10 +640,32 @@ } static void +rum_flush_task(struct usb2_proc_msg *pm) +{ + struct rum_task *task = (struct rum_task *)pm; + struct rum_softc *sc = task->sc; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + struct rum_vap *rvp = RUM_VAP(vap); + + /* callout it stopped */ + usb2_callout_stop(&rvp->amrr_ch); +} + +static void rum_vap_delete(struct ieee80211vap *vap) { struct rum_vap *rvp = RUM_VAP(vap); + struct rum_softc *sc = rvp->sc; + RUM_LOCK(sc); + /* wait for any pending tasks to complete */ + rum_queue_command(sc, rum_flush_task, + &sc->sc_synctask[0].hdr, + &sc->sc_synctask[1].hdr); + RUM_UNLOCK(sc); + usb2_callout_drain(&rvp->amrr_ch); ieee80211_amrr_cleanup(&rvp->amrr); ieee80211_vap_detach(vap); @@ -639,7 +688,6 @@ data->ni = NULL; } STAILQ_INSERT_TAIL(&sc->tx_free, data, next); - sc->tx_nfree++; } static void @@ -648,7 +696,6 @@ struct rum_tx_data *data; int i; - sc->tx_nfree = 0; STAILQ_INIT(&sc->tx_q); STAILQ_INIT(&sc->tx_free); @@ -657,7 +704,6 @@ data->sc = sc; STAILQ_INSERT_TAIL(&sc->tx_free, data, next); - sc->tx_nfree++; } } @@ -668,7 +714,6 @@ int i; /* make sure any subsequent use of the queues will fail */ - sc->tx_nfree = 0; STAILQ_INIT(&sc->tx_q); STAILQ_INIT(&sc->tx_free); @@ -698,12 +743,19 @@ struct rum_vap *rvp = RUM_VAP(vap); const struct ieee80211_txparam *tp; enum ieee80211_state ostate; + enum ieee80211_state nstate; struct ieee80211_node *ni; + int arg; uint32_t tmp; ostate = vap->iv_state; + nstate = sc->sc_state; + arg = sc->sc_arg; + + /* callout it stopped */ + usb2_callout_stop(&rvp->amrr_ch); - switch (sc->sc_state) { + switch (nstate) { case IEEE80211_S_INIT: if (ostate == IEEE80211_S_RUN) { /* abort TSF synchronization */ @@ -740,11 +792,17 @@ break; } + /* sanity checks */ + if (nstate == IEEE80211_S_INIT) + return; + if (nstate != sc->sc_state) + return; + RUM_UNLOCK(sc); IEEE80211_LOCK(ic); - rvp->newstate(vap, sc->sc_state, sc->sc_arg); + rvp->newstate(vap, nstate, arg); if (vap->iv_newstate_cb != NULL) - vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg); + vap->iv_newstate_cb(vap, nstate, arg); IEEE80211_UNLOCK(ic); RUM_LOCK(sc); } @@ -761,23 +819,19 @@ ieee80211_state_name[nstate]); RUM_LOCK(sc); - usb2_callout_stop(&rvp->amrr_ch); - /* do it in a process context */ sc->sc_state = nstate; sc->sc_arg = arg; + rum_queue_command(sc, rum_task, + &sc->sc_task[0].hdr, + &sc->sc_task[1].hdr); RUM_UNLOCK(sc); if (nstate == IEEE80211_S_INIT) { rvp->newstate(vap, nstate, arg); return 0; - } else { - RUM_LOCK(sc); - rum_queue_command(sc, rum_task, &sc->sc_task[0].hdr, - &sc->sc_task[1].hdr); - RUM_UNLOCK(sc); - return EINPROGRESS; } + return (EINPROGRESS); } static void @@ -791,6 +845,10 @@ struct mbuf *m; unsigned int len; + /* wakeup waiting command, if any */ + if (sc->sc_last_task != NULL) + cv_signal(&sc->sc_cmd_cv); + switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: DPRINTFN(11, "transfer complete, %d bytes\n", xfer->actlen); @@ -801,11 +859,14 @@ xfer->priv_fifo = NULL; ifp->if_opackets++; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; /* FALLTHROUGH */ case USB_ST_SETUP: tr_setup: + /* wait for command to complete, if any */ + if (sc->sc_last_task != NULL) + break; + data = STAILQ_FIRST(&sc->tx_q); if (data) { STAILQ_REMOVE_HEAD(&sc->tx_q, next); @@ -1042,8 +1103,6 @@ } } -#define RUM_TX_TIMEOUT 5000 - static int rum_sendprot(struct rum_softc *sc, const struct mbuf *m, struct ieee80211_node *ni, int prot, int rate) @@ -1079,11 +1138,14 @@ } if (mprot == NULL) { /* XXX stat + msg */ - return ENOBUFS; + return (ENOBUFS); } data = STAILQ_FIRST(&sc->tx_free); + if (data == NULL) { + m_freem(mprot); + return (ENOBUFS); + } STAILQ_REMOVE_HEAD(&sc->tx_free, next); - sc->tx_nfree--; data->m = mprot; data->ni = ieee80211_ref_node(ni); @@ -1112,8 +1174,11 @@ RUM_LOCK_ASSERT(sc, MA_OWNED); data = STAILQ_FIRST(&sc->tx_free); + if (data == NULL) { + m_freem(m0); + return (ENOBUFS); + } STAILQ_REMOVE_HEAD(&sc->tx_free, next); - sc->tx_nfree--; wh = mtod(m0, struct ieee80211_frame *); if (wh->i_fc[1] & IEEE80211_FC1_WEP) { @@ -1153,7 +1218,7 @@ STAILQ_INSERT_TAIL(&sc->tx_q, data, next); usb2_transfer_start(sc->sc_xfer[RUM_BULK_WR]); - return 0; + return (0); } static int @@ -1167,6 +1232,13 @@ RUM_LOCK_ASSERT(sc, MA_OWNED); KASSERT(params != NULL, ("no raw xmit params")); + data = STAILQ_FIRST(&sc->tx_free); + if (data == NULL) { + m_freem(m0); + return (ENOBUFS); + } + STAILQ_REMOVE_HEAD(&sc->tx_free, next); + rate = params->ibp_rate0 & IEEE80211_RATE_VAL; /* XXX validate */ if (rate == 0) { @@ -1181,17 +1253,13 @@ params->ibp_flags & IEEE80211_BPF_RTS ? IEEE80211_PROT_RTSCTS : IEEE80211_PROT_CTSONLY, rate); - if (error || sc->tx_nfree == 0) { + if (error) { m_freem(m0); - return ENOBUFS; + return error; } flags |= RT2573_TX_LONG_RETRY | RT2573_TX_IFS_SIFS; } - data = STAILQ_FIRST(&sc->tx_free); - STAILQ_REMOVE_HEAD(&sc->tx_free, next); - sc->tx_nfree--; - data->m = m0; data->ni = ni; data->rate = rate; @@ -1254,17 +1322,20 @@ prot = ic->ic_protmode; if (prot != IEEE80211_PROT_NONE) { error = rum_sendprot(sc, m0, ni, prot, rate); - if (error || sc->tx_nfree == 0) { + if (error) { m_freem(m0); - return ENOBUFS; + return error; } flags |= RT2573_TX_LONG_RETRY | RT2573_TX_IFS_SIFS; } } data = STAILQ_FIRST(&sc->tx_free); + if (data == NULL) { + m_freem(m0); + return (ENOBUFS); + } STAILQ_REMOVE_HEAD(&sc->tx_free, next); - sc->tx_nfree--; data->m = m0; data->ni = ni; @@ -1295,6 +1366,7 @@ { struct rum_softc *sc = ifp->if_softc; struct ieee80211_node *ni; + struct rum_tx_data *data; struct mbuf *m; RUM_LOCK(sc); @@ -1306,15 +1378,19 @@ IFQ_DRV_DEQUEUE(&ifp->if_snd, m); if (m == NULL) break; - if (sc->tx_nfree < RUM_TX_MINFREE) { - IFQ_DRV_PREPEND(&ifp->if_snd, m); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; + ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; + data = STAILQ_FIRST(&sc->tx_free); + if ((data == NULL) || (STAILQ_NEXT(data, next) == NULL)) { + /* last slot is reserved for mgt frame */ + m_freem(m); + ieee80211_free_node(ni); + ifp->if_oerrors++; + continue; } - ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; m = ieee80211_encap(ni, m); if (m == NULL) { ieee80211_free_node(ni); + ifp->if_oerrors++; continue; } if (rum_tx_data(sc, m, ni) != 0) { @@ -1375,7 +1451,6 @@ rum_eeprom_read(struct rum_softc *sc, uint16_t addr, void *buf, int len) { struct usb2_device_request req; - usb2_error_t error; req.bmRequestType = UT_READ_VENDOR_DEVICE; req.bRequest = RT2573_READ_EEPROM; @@ -1383,11 +1458,7 @@ USETW(req.wIndex, addr); USETW(req.wLength, len); - error = rum_do_request(sc, &req, buf); - if (error != 0) { - device_printf(sc->sc_dev, "could not read EEPROM: %s\n", - usb2_errstr(error)); - } + rum_do_request(sc, &req, buf); } static uint32_t @@ -1404,7 +1475,6 @@ rum_read_multi(struct rum_softc *sc, uint16_t reg, void *buf, int len) { struct usb2_device_request req; - usb2_error_t error; req.bmRequestType = UT_READ_VENDOR_DEVICE; req.bRequest = RT2573_READ_MULTI_MAC; @@ -1412,27 +1482,21 @@ USETW(req.wIndex, reg); USETW(req.wLength, len); - error = rum_do_request(sc, &req, buf); - if (error != 0) { - device_printf(sc->sc_dev, - "could not multi read MAC register: %s\n", - usb2_errstr(error)); - } + rum_do_request(sc, &req, buf); } -static void +static usb2_error_t rum_write(struct rum_softc *sc, uint16_t reg, uint32_t val) { uint32_t tmp = htole32(val); - rum_write_multi(sc, reg, &tmp, sizeof tmp); + return (rum_write_multi(sc, reg, &tmp, sizeof tmp)); } -static void +static usb2_error_t rum_write_multi(struct rum_softc *sc, uint16_t reg, void *buf, size_t len) { struct usb2_device_request req; - usb2_error_t error; req.bmRequestType = UT_WRITE_VENDOR_DEVICE; req.bRequest = RT2573_WRITE_MULTI_MAC; @@ -1440,12 +1504,7 @@ USETW(req.wIndex, reg); USETW(req.wLength, len); - error = rum_do_request(sc, &req, buf); - if (error != 0) { - device_printf(sc->sc_dev, - "could not multi write MAC register: %s\n", - usb2_errstr(error)); - } + return (rum_do_request(sc, &req, buf)); } static void @@ -1454,7 +1513,9 @@ uint32_t tmp; int ntries; - for (ntries = 0; ntries < 100; ntries++) { + DPRINTFN(2, "reg=0x%08x\n", reg); + + for (ntries = 0; ntries != 100; ntries++) { if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY)) break; if (rum_pause(sc, hz / 100)) @@ -1475,7 +1536,9 @@ uint32_t val; int ntries; - for (ntries = 0; ntries < 100; ntries++) { + DPRINTFN(2, "reg=0x%08x\n", reg); + + for (ntries = 0; ntries != 100; ntries++) { if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY)) break; if (rum_pause(sc, hz / 100)) @@ -1489,7 +1552,7 @@ val = RT2573_BBP_BUSY | RT2573_BBP_READ | reg << 8; rum_write(sc, RT2573_PHY_CSR3, val); - for (ntries = 0; ntries < 100; ntries++) { + for (ntries = 0; ntries != 100; ntries++) { val = rum_read(sc, RT2573_PHY_CSR3); if (!(val & RT2573_BBP_BUSY)) return val & 0xff; @@ -1507,7 +1570,7 @@ uint32_t tmp; int ntries; - for (ntries = 0; ntries < 100; ntries++) { + for (ntries = 0; ntries != 100; ntries++) { if (!(rum_read(sc, RT2573_PHY_CSR4) & RT2573_RF_BUSY)) break; if (rum_pause(sc, hz / 100)) @@ -1660,7 +1723,8 @@ const struct rfprog *rfprog; uint8_t bbp3, bbp94 = RT2573_BBPR94_DEFAULT; int8_t power; - int i, chan; + unsigned int i; + unsigned int chan; chan = ieee80211_chan2ieee(ic, c); if (chan == 0 || chan == IEEE80211_CHAN_ANY) @@ -1707,7 +1771,7 @@ rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7); rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10); - rum_pause(sc, hz / 100); + (void)rum_pause(sc, hz / 100); /* enable smart mode for MIMO-capable RFs */ bbp3 = rum_bbp_read(sc, 3); @@ -1720,6 +1784,9 @@ if (bbp94 != RT2573_BBPR94_DEFAULT) rum_bbp_write(sc, 94, bbp94); + + /* give the chip some extra time to do the switchover */ + (void)rum_pause(sc, hz / 100); } /* @@ -1817,6 +1884,27 @@ "entering" : "leaving"); } +static void +rum_update_mcast(struct ifnet *ifp) +{ + /* not supported */ +} + +static void +rum_update_promisc(struct ifnet *ifp) +{ + struct rum_softc *sc = ifp->if_softc; + + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + return; + + RUM_LOCK(sc); + rum_queue_command(sc, rum_promisctask, + &sc->sc_promisctask[0].hdr, + &sc->sc_promisctask[1].hdr); + RUM_UNLOCK(sc); +} + static const char * rum_get_rf(int rev) { @@ -1919,7 +2007,7 @@ int i, ntries; /* wait for BBP to be ready */ - for (ntries = 0; ntries < 100; ntries++) { + for (ntries = 0; ntries != 100; ntries++) { const uint8_t val = rum_bbp_read(sc, 0); if (val != 0 && val != 0xff) break; @@ -1971,7 +2059,7 @@ rum_write(sc, RT2573_MAC_CSR1, 0); /* wait for BBP/RF to wakeup */ - for (ntries = 0; ntries < 100; ntries++) { + for (ntries = 0; ntries != 100; ntries++) { if (rum_read(sc, RT2573_MAC_CSR12) & 8) break; rum_write(sc, RT2573_MAC_CSR12, 4); /* force wakeup */ @@ -2020,8 +2108,8 @@ } rum_write(sc, RT2573_TXRX_CSR0, tmp); - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; ifp->if_drv_flags |= IFF_DRV_RUNNING; + usb2_transfer_set_stall(sc->sc_xfer[RUM_BULK_WR]); usb2_transfer_start(sc->sc_xfer[RUM_BULK_RD]); return; @@ -2057,7 +2145,7 @@ RUM_LOCK_ASSERT(sc, MA_OWNED); - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + ifp->if_drv_flags &= ~IFF_DRV_RUNNING; RUM_UNLOCK(sc); @@ -2080,16 +2168,23 @@ rum_write(sc, RT2573_MAC_CSR1, 0); } -static int -rum_load_microcode(struct rum_softc *sc, const u_char *ucode, size_t size) +static void +rum_load_microcode(struct rum_softc *sc, const uint8_t *ucode, size_t size) { struct usb2_device_request req; uint16_t reg = RT2573_MCU_CODE_BASE; - usb2_error_t error; + usb2_error_t err; /* copy firmware image into NIC */ - for (; size >= 4; reg += 4, ucode += 4, size -= 4) - rum_write(sc, reg, UGETDW(ucode)); + for (; size >= 4; reg += 4, ucode += 4, size -= 4) { + err = rum_write(sc, reg, UGETDW(ucode)); + if (err) { + /* firmware already loaded ? */ + device_printf(sc->sc_dev, "Firmware load " + "failure! (ignored)\n"); + break; + } + } req.bmRequestType = UT_WRITE_VENDOR_DEVICE; req.bRequest = RT2573_MCU_CNTL; @@ -2097,12 +2192,10 @@ USETW(req.wIndex, 0); USETW(req.wLength, 0); - error = rum_do_request(sc, &req, NULL); - if (error != 0) { - device_printf(sc->sc_dev, "could not run firmware: %s\n", - usb2_errstr(error)); - } - return error; + rum_do_request(sc, &req, NULL); + + /* give the chip some time to boot */ + rum_pause(sc, hz / 8); } static int @@ -2149,13 +2242,6 @@ ieee80211_free_node(ni); return ENETDOWN; } - if (sc->tx_nfree < RUM_TX_MINFREE) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - RUM_UNLOCK(sc); - m_freem(m); - ieee80211_free_node(ni); - return EIO; - } ifp->if_opackets++; @@ -2195,7 +2281,9 @@ ieee80211_amrr_node_init(&rvp->amrr, &RUM_NODE(ni)->amn, ni); - usb2_callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, rvp); + /* XXX WLAN race --hps */ + if (sc->sc_state == IEEE80211_S_RUN) + usb2_callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, rvp); } static void @@ -2204,8 +2292,15 @@ struct rum_vap *rvp = arg; struct rum_softc *sc = rvp->sc; + /* XXX WLAN race --hps */ + if (sc->sc_state != IEEE80211_S_RUN) + return; + rum_queue_command(sc, rum_amrr_task, &rvp->amrr_task[0].hdr, &rvp->amrr_task[1].hdr); + + /* to avoid sync-issues we need to reset the callout here */ + usb2_callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, rvp); } static void @@ -2216,7 +2311,6 @@ struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); - struct rum_vap *rvp = RUM_VAP(vap); struct ieee80211_node *ni = vap->iv_bss; int ok, fail; @@ -2227,13 +2321,15 @@ (le32toh(sc->sta[5]) & 0xffff); /* TX ok w/ retry */ fail = (le32toh(sc->sta[5]) >> 16); /* TX retry-fail count */ + /* XXX WLAN race --hps */ + if (sc->sc_state != IEEE80211_S_RUN) + return; + ieee80211_amrr_tx_update(&RUM_NODE(ni)->amn, ok+fail, ok, (le32toh(sc->sta[5]) & 0xffff) + fail); (void) ieee80211_amrr_choose(ni, &RUM_NODE(ni)->amn); ifp->if_oerrors += fail; /* count TX retry-fail as Tx errors */ - - usb2_callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, rvp); } /* ARGUSED */ @@ -2374,8 +2470,8 @@ return rssi; } -static int -rum_pause(struct rum_softc *sc, int timeout) +static uint8_t +rum_pause(struct rum_softc *sc, unsigned int timeout) { if (usb2_proc_is_gone(&sc->sc_tq)) return (1); @@ -2385,6 +2481,33 @@ } static void +rum_command_wrapper(struct usb2_proc_msg *pm) +{ + struct rum_task *task = (struct rum_task *)pm; + struct rum_softc *sc = task->sc; + struct ifnet *ifp; + + /* wait for pending transfer, if any */ + while (usb2_transfer_pending(sc->sc_xfer[RUM_BULK_WR])) + cv_wait(&sc->sc_cmd_cv, &sc->sc_mtx); + + /* make sure any hardware buffers are emptied */ + rum_pause(sc, hz / 1000); + + /* execute task */ + task->func(pm); + + /* check if this is the last task executed */ + if (sc->sc_last_task == task) { + sc->sc_last_task = NULL; + ifp = sc->sc_ifp; + /* re-start TX, if any */ + if ((ifp != NULL) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) + usb2_transfer_start(sc->sc_xfer[RUM_BULK_WR]); + } +} + +static void rum_queue_command(struct rum_softc *sc, usb2_proc_callback_t *fn, struct usb2_proc_msg *t0, struct usb2_proc_msg *t1) { @@ -2392,10 +2515,6 @@ RUM_LOCK_ASSERT(sc, MA_OWNED); - if (usb2_proc_is_gone(&sc->sc_tq)) { - DPRINTF("proc is gone\n"); - return; /* nothing to do */ - } /* * NOTE: The task cannot get executed before we drop the * "sc_mtx" mutex. It is safe to update fields in the message @@ -2405,14 +2524,19 @@ usb2_proc_msignal(&sc->sc_tq, t0, t1); /* Setup callback and softc pointers */ - task->hdr.pm_callback = fn; + task->hdr.pm_callback = rum_command_wrapper; + task->func = fn; task->sc = sc; - /* - * Init and stop must be synchronous! - */ - if ((fn == rum_init_task) || (fn == rum_stop_task)) - usb2_proc_mwait(&sc->sc_tq, t0, t1); + /* Make sure that any TX operation will stop */ + sc->sc_last_task = task; + + /* + * Init, stop and flush must be synchronous! + */ + if ((fn == rum_init_task) || (fn == rum_stop_task) || + (fn == rum_flush_task)) + usb2_proc_mwait(&sc->sc_tq, t0, t1); } static device_method_t rum_methods[] = { ==== //depot/projects/usb/src/sys/dev/usb/wlan/if_rumfw.h#2 (text+ko) ==== @@ -1,4 +1,4 @@ -/* $FreeBSD: src/sys/dev/usb/wlan/if_rumfw.h,v 1.1 2009/02/23 18:31:00 thompsa Exp $ */ +/* $FreeBSD: user/thompsa/usb/sys/dev/usb2/wlan/if_rumfw.h 187190 2009-01-13 21:08:43Z thompsa $ */ /*- * Copyright (c) 2005-2006, Ralink Technology, Corp. ==== //depot/projects/usb/src/sys/dev/usb/wlan/if_rumreg.h#2 (text+ko) ==== ==== //depot/projects/usb/src/sys/dev/usb/wlan/if_rumvar.h#2 (text+ko) ==== @@ -1,4 +1,4 @@ -/* $FreeBSD: src/sys/dev/usb/wlan/if_rumvar.h,v 1.2 2009/02/23 23:46:56 thompsa Exp $ */ +/* $FreeBSD: src/sys/dev/usb2/wlan/if_rumvar.h,v 1.6 2009/02/09 22:18:11 thompsa Exp $ */ /*- * Copyright (c) 2005, 2006 Damien Bergamini <damien.bergamini@free.fr> @@ -18,7 +18,6 @@ */ #define RUM_TX_LIST_COUNT 8 -#define RUM_TX_MINFREE 2 struct rum_rx_radiotap_header { struct ieee80211_radiotap_header wr_ihdr; @@ -56,6 +55,7 @@ struct rum_task { struct usb2_proc_msg hdr; + usb2_proc_callback_t *func; struct rum_softc *sc; }; @@ -102,6 +102,7 @@ const struct ieee80211_rate_table *sc_rates; struct usb2_xfer *sc_xfer[RUM_N_TRANSFER]; + struct rum_task *sc_last_task; uint8_t rf_rev; uint8_t rffreq; @@ -120,9 +121,9 @@ struct rum_tx_data tx_data[RUM_TX_LIST_COUNT]; rum_txdhead tx_q; rum_txdhead tx_free; - int tx_nfree; struct rum_rx_desc sc_rx_desc; + struct cv sc_cmd_cv; struct mtx sc_mtx; uint32_t sta[6]; >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200902241817.n1OIHZpx010257>