Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F173971633
D4447.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D4447.diff
View Options
Index: head/sys/dev/usb/wlan/if_urtwn.c
===================================================================
--- head/sys/dev/usb/wlan/if_urtwn.c
+++ head/sys/dev/usb/wlan/if_urtwn.c
@@ -213,6 +213,9 @@
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 @@
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 @@
&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_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 @@
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)
{
Index: head/sys/dev/usb/wlan/if_urtwnvar.h
===================================================================
--- head/sys/dev/usb/wlan/if_urtwnvar.h
+++ head/sys/dev/usb/wlan/if_urtwnvar.h
@@ -71,15 +71,18 @@
};
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 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 @@
#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)
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Sep 30, 5:34 PM (3 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
39960670
Default Alt Text
D4447.diff (4 KB)
Attached To
Mode
D4447: urtwn: add a command queue for sleepable tasks
Attached
Detach File
Event Timeline
Log In to Comment