From owner-svn-src-head@freebsd.org Sat Oct 3 05:46:36 2015 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 9ABA5A0F675; Sat, 3 Oct 2015 05:46:36 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 7E47E11FD; Sat, 3 Oct 2015 05:46:36 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.70]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id t935kaqc019640; Sat, 3 Oct 2015 05:46:36 GMT (envelope-from adrian@FreeBSD.org) Received: (from adrian@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id t935kao5019638; Sat, 3 Oct 2015 05:46:36 GMT (envelope-from adrian@FreeBSD.org) Message-Id: <201510030546.t935kao5019638@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: adrian set sender to adrian@FreeBSD.org using -f From: Adrian Chadd Date: Sat, 3 Oct 2015 05:46:36 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r288532 - head/sys/dev/usb/wlan X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 03 Oct 2015 05:46:36 -0000 Author: adrian Date: Sat Oct 3 05:46:35 2015 New Revision: 288532 URL: https://svnweb.freebsd.org/changeset/base/288532 Log: rum(4): add command queue for running sleepable tasks in non-sleepable contexts Tested: * Tested on WUSB54GC, STA mode. * rum0: MAC/BBP RT2573 (rev 0x2573a), RF RT2528 Submitted by: Differential Revision: https://reviews.freebsd.org/D3629 Modified: head/sys/dev/usb/wlan/if_rum.c head/sys/dev/usb/wlan/if_rumvar.h Modified: head/sys/dev/usb/wlan/if_rum.c ============================================================================== --- head/sys/dev/usb/wlan/if_rum.c Sat Oct 3 05:44:05 2015 (r288531) +++ head/sys/dev/usb/wlan/if_rum.c Sat Oct 3 05:46:35 2015 (r288532) @@ -158,6 +158,9 @@ static struct ieee80211vap *rum_vap_crea int, const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN]); static void rum_vap_delete(struct ieee80211vap *); +static void rum_cmdq_cb(void *, int); +static int rum_cmd_sleepable(struct rum_softc *, const void *, + size_t, uint8_t, uint8_t, CMD_FUNC_PROTO); static void rum_tx_free(struct rum_tx_data *, int); static void rum_setup_tx_list(struct rum_softc *); static void rum_unsetup_tx_list(struct rum_softc *); @@ -438,8 +441,8 @@ rum_attach(device_t self) sc->sc_udev = uaa->device; sc->sc_dev = self; - mtx_init(&sc->sc_mtx, device_get_nameunit(self), - MTX_NETWORK_LOCK, MTX_DEF); + RUM_LOCK_INIT(sc); + RUM_CMDQ_LOCK_INIT(sc); mbufq_init(&sc->sc_snd, ifqmaxlen); iface_index = RT2573_IFACE_INDEX; @@ -516,6 +519,8 @@ rum_attach(device_t self) &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), RT2573_RX_RADIOTAP_PRESENT); + TASK_INIT(&sc->cmdq_task, 0, rum_cmdq_cb, sc); + if (bootverbose) ieee80211_announce(ic); @@ -545,10 +550,15 @@ rum_detach(device_t self) rum_unsetup_tx_list(sc); RUM_UNLOCK(sc); - if (ic->ic_softc == sc) + if (ic->ic_softc == sc) { + ieee80211_draintask(ic, &sc->cmdq_task); ieee80211_ifdetach(ic); + } + mbufq_drain(&sc->sc_snd); - mtx_destroy(&sc->sc_mtx); + RUM_CMDQ_LOCK_DESTROY(sc); + RUM_LOCK_DESTROY(sc); + return (0); } @@ -625,6 +635,57 @@ rum_vap_delete(struct ieee80211vap *vap) } static void +rum_cmdq_cb(void *arg, int pending) +{ + struct rum_softc *sc = arg; + struct rum_cmdq *rc; + + RUM_CMDQ_LOCK(sc); + while (sc->cmdq[sc->cmdq_first].func != NULL) { + rc = &sc->cmdq[sc->cmdq_first]; + RUM_CMDQ_UNLOCK(sc); + + RUM_LOCK(sc); + rc->func(sc, &rc->data, rc->rn_id, rc->rvp_id); + RUM_UNLOCK(sc); + + RUM_CMDQ_LOCK(sc); + memset(rc, 0, sizeof (*rc)); + sc->cmdq_first = (sc->cmdq_first + 1) % RUM_CMDQ_SIZE; + } + RUM_CMDQ_UNLOCK(sc); +} + +static int +rum_cmd_sleepable(struct rum_softc *sc, const void *ptr, size_t len, + uint8_t rn_id, uint8_t rvp_id, CMD_FUNC_PROTO) +{ + struct ieee80211com *ic = &sc->sc_ic; + + KASSERT(len <= sizeof(union sec_param), ("buffer overflow")); + + RUM_CMDQ_LOCK(sc); + if (sc->cmdq[sc->cmdq_last].func != NULL) { + device_printf(sc->sc_dev, "%s: cmdq overflow\n", __func__); + RUM_CMDQ_UNLOCK(sc); + + return EAGAIN; + } + + if (ptr != NULL) + memcpy(&sc->cmdq[sc->cmdq_last].data, ptr, len); + sc->cmdq[sc->cmdq_last].rn_id = rn_id; + sc->cmdq[sc->cmdq_last].rvp_id = rvp_id; + sc->cmdq[sc->cmdq_last].func = func; + sc->cmdq_last = (sc->cmdq_last + 1) % RUM_CMDQ_SIZE; + RUM_CMDQ_UNLOCK(sc); + + ieee80211_runtask(ic, &sc->cmdq_task); + + return 0; +} + +static void rum_tx_free(struct rum_tx_data *data, int txerr) { struct rum_softc *sc = data->sc; Modified: head/sys/dev/usb/wlan/if_rumvar.h ============================================================================== --- head/sys/dev/usb/wlan/if_rumvar.h Sat Oct 3 05:44:05 2015 (r288531) +++ head/sys/dev/usb/wlan/if_rumvar.h Sat Oct 3 05:46:35 2015 (r288532) @@ -67,6 +67,25 @@ struct rum_tx_data { }; typedef STAILQ_HEAD(, rum_tx_data) rum_txdhead; +union sec_param { + struct ieee80211_key key; + uint8_t macaddr[IEEE80211_ADDR_LEN]; + struct ieee80211vap *vap; +}; +#define CMD_FUNC_PROTO void (*func)(struct rum_softc *, \ + union sec_param *, uint8_t, \ + uint8_t) + +struct rum_cmdq { + union sec_param data; + + uint8_t rn_id; + uint8_t rvp_id; + + CMD_FUNC_PROTO; +}; +#define RUM_CMDQ_SIZE 16 + struct rum_vap { struct ieee80211vap vap; struct ieee80211_beacon_offsets bo; @@ -103,6 +122,12 @@ struct rum_softc { struct mtx sc_mtx; + struct rum_cmdq cmdq[RUM_CMDQ_SIZE]; + struct mtx cmdq_mtx; + struct task cmdq_task; + uint8_t cmdq_first; + uint8_t cmdq_last; + uint32_t sta[6]; uint32_t rf_regs[4]; uint8_t txpow[44]; @@ -128,6 +153,16 @@ struct rum_softc { struct rum_tx_radiotap_header sc_txtap; }; -#define RUM_LOCK(sc) mtx_lock(&(sc)->sc_mtx) -#define RUM_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) -#define RUM_LOCK_ASSERT(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED) +#define RUM_LOCK_INIT(sc) \ + mtx_init(&(sc)->sc_mtx, device_get_nameunit((sc)->sc_dev), \ + MTX_NETWORK_LOCK, MTX_DEF); +#define RUM_LOCK(sc) mtx_lock(&(sc)->sc_mtx) +#define RUM_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) +#define RUM_LOCK_ASSERT(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED) +#define RUM_LOCK_DESTROY(sc) mtx_destroy(&(sc)->sc_mtx) + +#define RUM_CMDQ_LOCK_INIT(sc) \ + mtx_init(&(sc)->cmdq_mtx, "cmdq lock", NULL, MTX_DEF) +#define RUM_CMDQ_LOCK(sc) mtx_lock(&(sc)->cmdq_mtx) +#define RUM_CMDQ_UNLOCK(sc) mtx_unlock(&(sc)->cmdq_mtx) +#define RUM_CMDQ_LOCK_DESTROY(sc) mtx_destroy(&(sc)->cmdq_mtx)