From owner-svn-src-all@freebsd.org Sun Dec 13 21:50:39 2015 Return-Path: Delivered-To: svn-src-all@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 8EFABA42EE6; Sun, 13 Dec 2015 21:50:39 +0000 (UTC) (envelope-from avos@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::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 510771BA3; Sun, 13 Dec 2015 21:50:39 +0000 (UTC) (envelope-from avos@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id tBDLocbg093733; Sun, 13 Dec 2015 21:50:38 GMT (envelope-from avos@FreeBSD.org) Received: (from avos@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id tBDLockD093731; Sun, 13 Dec 2015 21:50:38 GMT (envelope-from avos@FreeBSD.org) Message-Id: <201512132150.tBDLockD093731@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: avos set sender to avos@FreeBSD.org using -f From: Andriy Voskoboinyk Date: Sun, 13 Dec 2015 21:50:38 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r292174 - 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-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 13 Dec 2015 21:50:39 -0000 Author: avos Date: Sun Dec 13 21:50:38 2015 New Revision: 292174 URL: https://svnweb.freebsd.org/changeset/base/292174 Log: urtwn: add a command queue for sleepable tasks. An implementation from rum(4) was used (it looks simpler for me). Will be used for h/w encryption support. Reviewed by: kevlo Approved by: adrian (mentor) Differential Revision: https://reviews.freebsd.org/D4447 Modified: head/sys/dev/usb/wlan/if_urtwn.c head/sys/dev/usb/wlan/if_urtwnvar.h Modified: head/sys/dev/usb/wlan/if_urtwn.c ============================================================================== --- head/sys/dev/usb/wlan/if_urtwn.c Sun Dec 13 21:43:54 2015 (r292173) +++ head/sys/dev/usb/wlan/if_urtwn.c Sun Dec 13 21:50:38 2015 (r292174) @@ -213,6 +213,9 @@ static uint16_t urtwn_read_2(struct urt static uint32_t urtwn_read_4(struct urtwn_softc *, uint16_t); static int urtwn_fw_cmd(struct urtwn_softc *, uint8_t, const void *, int); +static void urtwn_cmdq_cb(void *, int); +static int urtwn_cmd_sleepable(struct urtwn_softc *, const void *, + size_t, CMD_FUNC_PROTO); static void urtwn_r92c_rf_write(struct urtwn_softc *, int, uint8_t, uint32_t); static void urtwn_r88e_rf_write(struct urtwn_softc *, int, @@ -427,6 +430,7 @@ urtwn_attach(device_t self) mtx_init(&sc->sc_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK, MTX_DEF); + URTWN_CMDQ_LOCK_INIT(sc); URTWN_NT_LOCK_INIT(sc); callout_init(&sc->sc_watchdog_ch, 0); mbufq_init(&sc->sc_snd, ifqmaxlen); @@ -525,6 +529,8 @@ urtwn_attach(device_t self) &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), URTWN_RX_RADIOTAP_PRESENT); + TASK_INIT(&sc->cmdq_task, 0, urtwn_cmdq_cb, sc); + if (bootverbose) ieee80211_announce(ic); @@ -574,8 +580,13 @@ urtwn_detach(device_t self) urtwn_free_rx_list(sc); URTWN_UNLOCK(sc); - ieee80211_ifdetach(ic); + if (ic->ic_softc == sc) { + ieee80211_draintask(ic, &sc->cmdq_task); + ieee80211_ifdetach(ic); + } + URTWN_NT_LOCK_DESTROY(sc); + URTWN_CMDQ_LOCK_DESTROY(sc); mtx_destroy(&sc->sc_mtx); return (0); @@ -1259,6 +1270,64 @@ urtwn_fw_cmd(struct urtwn_softc *sc, uin return (0); } +static void +urtwn_cmdq_cb(void *arg, int pending) +{ + struct urtwn_softc *sc = arg; + struct urtwn_cmdq *item; + + /* + * Device must be powered on (via urtwn_power_on()) + * before any command may be sent. + */ + URTWN_LOCK(sc); + if (!(sc->sc_flags & URTWN_RUNNING)) { + URTWN_UNLOCK(sc); + return; + } + + URTWN_CMDQ_LOCK(sc); + while (sc->cmdq[sc->cmdq_first].func != NULL) { + item = &sc->cmdq[sc->cmdq_first]; + sc->cmdq_first = (sc->cmdq_first + 1) % URTWN_CMDQ_SIZE; + URTWN_CMDQ_UNLOCK(sc); + + item->func(sc, &item->data); + + URTWN_CMDQ_LOCK(sc); + memset(item, 0, sizeof (*item)); + } + URTWN_CMDQ_UNLOCK(sc); + URTWN_UNLOCK(sc); +} + +static int +urtwn_cmd_sleepable(struct urtwn_softc *sc, const void *ptr, size_t len, + CMD_FUNC_PROTO) +{ + struct ieee80211com *ic = &sc->sc_ic; + + KASSERT(len <= sizeof(union sec_param), ("buffer overflow")); + + URTWN_CMDQ_LOCK(sc); + if (sc->cmdq[sc->cmdq_last].func != NULL) { + device_printf(sc->sc_dev, "%s: cmdq overflow\n", __func__); + URTWN_CMDQ_UNLOCK(sc); + + return (EAGAIN); + } + + if (ptr != NULL) + memcpy(&sc->cmdq[sc->cmdq_last].data, ptr, len); + sc->cmdq[sc->cmdq_last].func = func; + sc->cmdq_last = (sc->cmdq_last + 1) % URTWN_CMDQ_SIZE; + URTWN_CMDQ_UNLOCK(sc); + + ieee80211_runtask(ic, &sc->cmdq_task); + + return (0); +} + static __inline void urtwn_rf_write(struct urtwn_softc *sc, int chain, uint8_t addr, uint32_t val) { Modified: head/sys/dev/usb/wlan/if_urtwnvar.h ============================================================================== --- head/sys/dev/usb/wlan/if_urtwnvar.h Sun Dec 13 21:43:54 2015 (r292173) +++ head/sys/dev/usb/wlan/if_urtwnvar.h Sun Dec 13 21:50:38 2015 (r292174) @@ -71,15 +71,18 @@ struct urtwn_data { }; typedef STAILQ_HEAD(, urtwn_data) urtwn_datahead; +union sec_param { + struct ieee80211_key key; +}; + +#define CMD_FUNC_PROTO void (*func)(struct urtwn_softc *, \ + union sec_param *) + struct urtwn_cmdq { - void *arg0; - void *arg1; - void (*func)(void *); - struct ieee80211_key *k; - struct ieee80211_key key; - uint8_t mac[IEEE80211_ADDR_LEN]; - uint8_t wcid; + union sec_param data; + CMD_FUNC_PROTO; }; +#define URTWN_CMDQ_SIZE 16 struct urtwn_fw_info { const uint8_t *data; @@ -203,17 +206,11 @@ struct urtwn_softc { struct callout sc_watchdog_ch; struct mtx sc_mtx; -/* need to be power of 2, otherwise URTWN_CMDQ_GET fails */ -#define URTWN_CMDQ_MAX 16 -#define URTWN_CMDQ_MASQ (URTWN_CMDQ_MAX - 1) - struct urtwn_cmdq cmdq[URTWN_CMDQ_MAX]; + struct urtwn_cmdq cmdq[URTWN_CMDQ_SIZE]; + struct mtx cmdq_mtx; struct task cmdq_task; - uint32_t cmdq_store; - uint8_t cmdq_exec; - uint8_t cmdq_run; - uint8_t cmdq_key_set; -#define URTWN_CMDQ_ABORT 0 -#define URTWN_CMDQ_GO 1 + uint8_t cmdq_first; + uint8_t cmdq_last; uint32_t rf_chnlbw[R92C_MAX_CHAINS]; struct usb_xfer *sc_xfer[URTWN_N_TRANSFER]; @@ -226,6 +223,12 @@ struct urtwn_softc { #define URTWN_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) #define URTWN_ASSERT_LOCKED(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED) +#define URTWN_CMDQ_LOCK_INIT(sc) \ + mtx_init(&(sc)->cmdq_mtx, "cmdq lock", NULL, MTX_DEF) +#define URTWN_CMDQ_LOCK(sc) mtx_lock(&(sc)->cmdq_mtx) +#define URTWN_CMDQ_UNLOCK(sc) mtx_unlock(&(sc)->cmdq_mtx) +#define URTWN_CMDQ_LOCK_DESTROY(sc) mtx_destroy(&(sc)->cmdq_mtx) + #define URTWN_NT_LOCK_INIT(sc) \ mtx_init(&(sc)->nt_mtx, "node table lock", NULL, MTX_DEF) #define URTWN_NT_LOCK(sc) mtx_lock(&(sc)->nt_mtx)