Page MenuHomeFreeBSD

D4447.diff
No OneTemporary

D4447.diff

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

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)

Event Timeline