summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Wildt <patrick@cvs.openbsd.org>2019-07-05 12:35:17 +0000
committerPatrick Wildt <patrick@cvs.openbsd.org>2019-07-05 12:35:17 +0000
commit9cbc54e735d6ae43aa0a659fea1ac4384236407a (patch)
tree43ceedb92bc2dd4ece644137b4603a8fdd05ac5d
parent78cb2532be3115ceffb7b842509a0eb79206ec82 (diff)
Since on a SCAN each node is provided in its own event,
the limited ring for asynchronous can easily overflow. Work around this by chaining the mbufs into a list. Fixes a panic for jcs@ ok stsp@
-rw-r--r--sys/dev/ic/bwfm.c27
-rw-r--r--sys/dev/ic/bwfmvar.h7
2 files changed, 21 insertions, 13 deletions
diff --git a/sys/dev/ic/bwfm.c b/sys/dev/ic/bwfm.c
index 622a4ffb751..461f33f2561 100644
--- a/sys/dev/ic/bwfm.c
+++ b/sys/dev/ic/bwfm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bwfm.c,v 1.62 2019/05/22 15:25:25 patrick Exp $ */
+/* $OpenBSD: bwfm.c,v 1.63 2019/07/05 12:35:16 patrick Exp $ */
/*
* Copyright (c) 2010-2016 Broadcom Corporation
* Copyright (c) 2016,2017 Patrick Wildt <patrick@blueri.se>
@@ -131,7 +131,7 @@ int bwfm_newstate(struct ieee80211com *, enum ieee80211_state, int);
void bwfm_set_key_cb(struct bwfm_softc *, void *);
void bwfm_delete_key_cb(struct bwfm_softc *, void *);
-void bwfm_rx_event_cb(struct bwfm_softc *, void *);
+void bwfm_rx_event_cb(struct bwfm_softc *, struct mbuf *);
struct mbuf *bwfm_newbuf(void);
void bwfm_rx(struct bwfm_softc *, struct mbuf *);
@@ -181,6 +181,7 @@ bwfm_attach(struct bwfm_softc *sc)
sc->sc_cmdq.cur = sc->sc_cmdq.next = sc->sc_cmdq.queued = 0;
sc->sc_taskq = taskq_create(DEVNAME(sc), 1, IPL_SOFTNET, 0);
task_set(&sc->sc_task, bwfm_task, sc);
+ ml_init(&sc->sc_evml);
ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
@@ -2234,19 +2235,20 @@ bwfm_rx_leave_ind(struct bwfm_softc *sc, struct bwfm_event *e, size_t len,
void
bwfm_rx_event(struct bwfm_softc *sc, struct mbuf *m)
{
- struct bwfm_cmd_mbuf cmd;
+ int s;
+
+ s = splsoftnet();
+ ml_enqueue(&sc->sc_evml, m);
+ splx(s);
- cmd.m = m;
- bwfm_do_async(sc, bwfm_rx_event_cb, &cmd, sizeof(cmd));
+ task_add(sc->sc_taskq, &sc->sc_task);
}
void
-bwfm_rx_event_cb(struct bwfm_softc *sc, void *arg)
+bwfm_rx_event_cb(struct bwfm_softc *sc, struct mbuf *m)
{
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = &ic->ic_if;
- struct bwfm_cmd_mbuf *cmd = arg;
- struct mbuf *m = cmd->m;
struct bwfm_event *e = mtod(m, void *);
size_t len = m->m_len;
@@ -2429,6 +2431,7 @@ bwfm_task(void *arg)
struct bwfm_softc *sc = arg;
struct bwfm_host_cmd_ring *ring = &sc->sc_cmdq;
struct bwfm_host_cmd *cmd;
+ struct mbuf *m;
int s;
s = splsoftnet();
@@ -2441,6 +2444,14 @@ bwfm_task(void *arg)
ring->next = (ring->next + 1) % BWFM_HOST_CMD_RING_COUNT;
}
splx(s);
+
+ s = splsoftnet();
+ while ((m = ml_dequeue(&sc->sc_evml)) != NULL) {
+ splx(s);
+ bwfm_rx_event_cb(sc, m);
+ s = splsoftnet();
+ }
+ splx(s);
}
void
diff --git a/sys/dev/ic/bwfmvar.h b/sys/dev/ic/bwfmvar.h
index 7ea91a21a28..c09bc87704c 100644
--- a/sys/dev/ic/bwfmvar.h
+++ b/sys/dev/ic/bwfmvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bwfmvar.h,v 1.15 2018/07/17 19:44:38 patrick Exp $ */
+/* $OpenBSD: bwfmvar.h,v 1.16 2019/07/05 12:35:16 patrick Exp $ */
/*
* Copyright (c) 2010-2016 Broadcom Corporation
* Copyright (c) 2016,2017 Patrick Wildt <patrick@blueri.se>
@@ -121,10 +121,6 @@ struct bwfm_cmd_key {
struct ieee80211_key *k;
};
-struct bwfm_cmd_mbuf {
- struct mbuf *m;
-};
-
struct bwfm_cmd_flowring_create {
struct mbuf *m;
int flowid;
@@ -167,6 +163,7 @@ struct bwfm_softc {
struct bwfm_host_cmd_ring sc_cmdq;
struct taskq *sc_taskq;
struct task sc_task;
+ struct mbuf_list sc_evml;
int sc_bcdc_reqid;
TAILQ_HEAD(, bwfm_proto_bcdc_ctl) sc_bcdc_rxctlq;