summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Sperling <stsp@cvs.openbsd.org>2019-09-12 12:55:08 +0000
committerStefan Sperling <stsp@cvs.openbsd.org>2019-09-12 12:55:08 +0000
commitbf1d600d09a5e6bd03f65236695ceb27eee54583 (patch)
tree61b19e1ac5df4f2d3e59772380c88bda5b54db33
parentcdd78b5d4dc581ea298f7e14e7b2403c27de216f (diff)
Make wireless drivers call if_input() only once per interrupt.
This reduces drops caused by the ifq pressure drop mechanism and hence increases throughput. Such drops are visible with e.g. 'netstat -dnI iwm0'. Not all affected drivers have been tested yet but these changes are largely mechanical and should be safe. As usual, please report any regressions. With help from dlg@ and mpi@ Problem found by robert@ Tested by robert, jmc, Tracey Emer, Matthias Schmidt, florian, Björn Ketelaars ok mpi@
-rw-r--r--sys/dev/ic/ar5008.c14
-rw-r--r--sys/dev/ic/ar9003.c16
-rw-r--r--sys/dev/ic/ath.c9
-rw-r--r--sys/dev/ic/atw.c6
-rw-r--r--sys/dev/ic/bwi.c6
-rw-r--r--sys/dev/ic/malo.c6
-rw-r--r--sys/dev/ic/pgt.c6
-rw-r--r--sys/dev/ic/rt2560.c6
-rw-r--r--sys/dev/ic/rt2661.c6
-rw-r--r--sys/dev/ic/rt2860.c6
-rw-r--r--sys/dev/ic/rtw.c6
-rw-r--r--sys/dev/pci/if_ipw.c13
-rw-r--r--sys/dev/pci/if_iwi.c12
-rw-r--r--sys/dev/pci/if_iwm.c14
-rw-r--r--sys/dev/pci/if_iwn.c14
-rw-r--r--sys/dev/pci/if_rtwn.c21
-rw-r--r--sys/dev/pci/if_wpi.c12
-rw-r--r--sys/dev/usb/if_athn_usb.c16
-rw-r--r--sys/dev/usb/if_otus.c14
-rw-r--r--sys/dev/usb/if_rsu.c14
-rw-r--r--sys/dev/usb/if_run.c14
-rw-r--r--sys/dev/usb/if_urtwn.c15
-rw-r--r--sys/dev/usb/if_zyd.c16
-rw-r--r--sys/net80211/ieee80211_input.c111
-rw-r--r--sys/net80211/ieee80211_proto.h5
25 files changed, 241 insertions, 137 deletions
diff --git a/sys/dev/ic/ar5008.c b/sys/dev/ic/ar5008.c
index d72e8edcead..f58d36a19ca 100644
--- a/sys/dev/ic/ar5008.c
+++ b/sys/dev/ic/ar5008.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ar5008.c,v 1.51 2019/07/24 07:53:57 stsp Exp $ */
+/* $OpenBSD: ar5008.c,v 1.52 2019/09/12 12:55:06 stsp Exp $ */
/*-
* Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
@@ -789,7 +789,7 @@ ar5008_rx_radiotap(struct athn_softc *sc, struct mbuf *m,
#endif
static __inline int
-ar5008_rx_process(struct athn_softc *sc)
+ar5008_rx_process(struct athn_softc *sc, struct mbuf_list *ml)
{
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = &ic->ic_if;
@@ -931,7 +931,7 @@ ar5008_rx_process(struct athn_softc *sc)
rxi.rxi_rssi = MS(ds->ds_status4, AR_RXS4_RSSI_COMBINED);
rxi.rxi_rssi += AR_DEFAULT_NOISE_FLOOR;
rxi.rxi_tstamp = ds->ds_status2;
- ieee80211_input(ifp, m, ni, &rxi);
+ ieee80211_inputm(ifp, m, ni, &rxi, ml);
/* Node is no longer needed. */
ieee80211_release_node(ic, ni);
@@ -960,7 +960,13 @@ ar5008_rx_process(struct athn_softc *sc)
void
ar5008_rx_intr(struct athn_softc *sc)
{
- while (ar5008_rx_process(sc) == 0);
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = &ic->ic_if;
+
+ while (ar5008_rx_process(sc, &ml) == 0);
+
+ if_input(ifp, &ml);
}
int
diff --git a/sys/dev/ic/ar9003.c b/sys/dev/ic/ar9003.c
index 69ade5ade5a..ca4a71dbeaa 100644
--- a/sys/dev/ic/ar9003.c
+++ b/sys/dev/ic/ar9003.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ar9003.c,v 1.48 2019/02/19 10:17:09 stsp Exp $ */
+/* $OpenBSD: ar9003.c,v 1.49 2019/09/12 12:55:06 stsp Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
@@ -83,7 +83,7 @@ void ar9003_reset_txsring(struct athn_softc *);
void ar9003_rx_enable(struct athn_softc *);
void ar9003_rx_radiotap(struct athn_softc *, struct mbuf *,
struct ar_rx_status *);
-int ar9003_rx_process(struct athn_softc *, int);
+int ar9003_rx_process(struct athn_softc *, int, struct mbuf_list *);
void ar9003_rx_intr(struct athn_softc *, int);
int ar9003_tx_process(struct athn_softc *);
void ar9003_tx_intr(struct athn_softc *);
@@ -916,7 +916,7 @@ ar9003_rx_radiotap(struct athn_softc *sc, struct mbuf *m,
#endif
int
-ar9003_rx_process(struct athn_softc *sc, int qid)
+ar9003_rx_process(struct athn_softc *sc, int qid, struct mbuf_list *ml)
{
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = &ic->ic_if;
@@ -1036,7 +1036,7 @@ ar9003_rx_process(struct athn_softc *sc, int qid)
rxi.rxi_flags = 0; /* XXX */
rxi.rxi_rssi = MS(ds->ds_status5, AR_RXS5_RSSI_COMBINED);
rxi.rxi_tstamp = ds->ds_status3;
- ieee80211_input(ifp, m, ni, &rxi);
+ ieee80211_inputm(ifp, m, ni, &rxi, ml);
/* Node is no longer needed. */
ieee80211_release_node(ic, ni);
@@ -1066,7 +1066,13 @@ ar9003_rx_process(struct athn_softc *sc, int qid)
void
ar9003_rx_intr(struct athn_softc *sc, int qid)
{
- while (ar9003_rx_process(sc, qid) == 0);
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
+ struct ieee80211com *ic = &sc->sc_ic;
+ struct ifnet *ifp = &ic->ic_if;
+
+ while (ar9003_rx_process(sc, qid, &ml) == 0);
+
+ if_input(ifp, &ml);
}
int
diff --git a/sys/dev/ic/ath.c b/sys/dev/ic/ath.c
index c0c5f4241b0..dd571921ddc 100644
--- a/sys/dev/ic/ath.c
+++ b/sys/dev/ic/ath.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ath.c,v 1.116 2018/01/31 11:27:03 stsp Exp $ */
+/* $OpenBSD: ath.c,v 1.117 2019/09/12 12:55:06 stsp Exp $ */
/* $NetBSD: ath.c,v 1.37 2004/08/18 21:59:39 dyoung Exp $ */
/*-
@@ -1795,6 +1795,7 @@ ath_rxbuf_init(struct ath_softc *sc, struct ath_buf *bf)
void
ath_rx_proc(void *arg, int npending)
{
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
#define PA2DESC(_sc, _pa) \
((struct ath_desc *)((caddr_t)(_sc)->sc_desc + \
((_pa) - (_sc)->sc_desc_paddr)))
@@ -1946,7 +1947,7 @@ ath_rx_proc(void *arg, int npending)
if (!ath_softcrypto && (wh->i_fc[1] & IEEE80211_FC1_WEP)) {
/*
* WEP is decrypted by hardware. Clear WEP bit
- * and trim WEP header for ieee80211_input().
+ * and trim WEP header for ieee80211_inputm().
*/
wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
bcopy(wh, &whbuf, sizeof(whbuf));
@@ -1988,7 +1989,7 @@ ath_rx_proc(void *arg, int npending)
*/
rxi.rxi_rssi = ds->ds_rxstat.rs_rssi;
rxi.rxi_tstamp = ds->ds_rxstat.rs_tstamp;
- ieee80211_input(ifp, m, ni, &rxi);
+ ieee80211_inputm(ifp, m, ni, &rxi, &ml);
/* Handle the rate adaption */
ieee80211_rssadapt_input(ic, ni, &an->an_rssadapt,
@@ -2005,6 +2006,8 @@ ath_rx_proc(void *arg, int npending)
TAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list);
} while (ath_rxbuf_init(sc, bf) == 0);
+ if_input(ifp, &ml);
+
ath_hal_set_rx_signal(ah); /* rx signal state monitoring */
ath_hal_start_rx(ah); /* in case of RXEOL */
#undef PA2DESC
diff --git a/sys/dev/ic/atw.c b/sys/dev/ic/atw.c
index cbf21da7400..cf80921d5d4 100644
--- a/sys/dev/ic/atw.c
+++ b/sys/dev/ic/atw.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: atw.c,v 1.96 2017/09/22 13:44:00 kevlo Exp $ */
+/* $OpenBSD: atw.c,v 1.97 2019/09/12 12:55:07 stsp Exp $ */
/* $NetBSD: atw.c,v 1.69 2004/07/23 07:07:55 dyoung Exp $ */
/*-
@@ -3029,6 +3029,7 @@ atw_hw_decrypted(struct atw_softc *sc, struct ieee80211_frame *wh)
void
atw_rxintr(struct atw_softc *sc)
{
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
static int rate_tbl[] = {2, 4, 11, 22, 44};
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_rxinfo rxi;
@@ -3183,7 +3184,7 @@ atw_rxintr(struct atw_softc *sc)
#endif
rxi.rxi_rssi = (int)rssi;
rxi.rxi_tstamp = 0;
- ieee80211_input(ifp, m, ni, &rxi);
+ ieee80211_inputm(ifp, m, ni, &rxi, &ml);
/*
* The frame may have caused the node to be marked for
* reclamation (e.g. in response to a DEAUTH message)
@@ -3191,6 +3192,7 @@ atw_rxintr(struct atw_softc *sc)
*/
ieee80211_release_node(ic, ni);
}
+ if_input(ifp, &ml);
/* Update the receive pointer. */
sc->sc_rxptr = i;
diff --git a/sys/dev/ic/bwi.c b/sys/dev/ic/bwi.c
index 58417ce6f7d..679fda47fa8 100644
--- a/sys/dev/ic/bwi.c
+++ b/sys/dev/ic/bwi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bwi.c,v 1.127 2017/10/26 15:00:28 mpi Exp $ */
+/* $OpenBSD: bwi.c,v 1.128 2019/09/12 12:55:07 stsp Exp $ */
/*
* Copyright (c) 2007 The DragonFly Project. All rights reserved.
@@ -8355,6 +8355,7 @@ bwi_next_scan(void *xsc)
int
bwi_rxeof(struct bwi_softc *sc, int end_idx)
{
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
struct bwi_ring_data *rd = &sc->sc_rx_rdata;
struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
struct ieee80211com *ic = &sc->sc_ic;
@@ -8455,7 +8456,7 @@ bwi_rxeof(struct bwi_softc *sc, int end_idx)
rxi.rxi_rssi = hdr->rxh_rssi;
rxi.rxi_tstamp = letoh16(hdr->rxh_tsf);
- ieee80211_input(ifp, m, ni, &rxi);
+ ieee80211_inputm(ifp, m, ni, &rxi, &ml);
ieee80211_release_node(ic, ni);
@@ -8466,6 +8467,7 @@ bwi_rxeof(struct bwi_softc *sc, int end_idx)
next:
idx = (idx + 1) % BWI_RX_NDESC;
}
+ if_input(ifp, &ml);
rbd->rbd_idx = idx;
bus_dmamap_sync(sc->sc_dmat, rd->rdata_dmap, 0,
diff --git a/sys/dev/ic/malo.c b/sys/dev/ic/malo.c
index 6a8c5646f0b..6f8d9a1e44c 100644
--- a/sys/dev/ic/malo.c
+++ b/sys/dev/ic/malo.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: malo.c,v 1.118 2018/11/09 14:14:31 claudio Exp $ */
+/* $OpenBSD: malo.c,v 1.119 2019/09/12 12:55:07 stsp Exp $ */
/*
* Copyright (c) 2006 Claudio Jeker <claudio@openbsd.org>
@@ -1593,6 +1593,7 @@ malo_tx_setup_desc(struct malo_softc *sc, struct malo_tx_desc *desc,
void
malo_rx_intr(struct malo_softc *sc)
{
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = &ic->ic_if;
struct malo_rx_desc *desc;
@@ -1711,7 +1712,7 @@ malo_rx_intr(struct malo_softc *sc)
rxi.rxi_flags = 0;
rxi.rxi_rssi = desc->rssi;
rxi.rxi_tstamp = 0; /* unused */
- ieee80211_input(ifp, m, ni, &rxi);
+ ieee80211_inputm(ifp, m, ni, &rxi, &ml);
/* node is no longer needed */
ieee80211_release_node(ic, ni);
@@ -1727,6 +1728,7 @@ skip:
sc->sc_rxring.cur = (sc->sc_rxring.cur + 1) %
MALO_RX_RING_COUNT;
}
+ if_input(ifp, &ml);
malo_mem_write4(sc, sc->sc_RxPdRdPtr, rxRdPtr);
}
diff --git a/sys/dev/ic/pgt.c b/sys/dev/ic/pgt.c
index f4426464509..eb8f2a934a3 100644
--- a/sys/dev/ic/pgt.c
+++ b/sys/dev/ic/pgt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pgt.c,v 1.94 2019/08/27 14:57:48 stsp Exp $ */
+/* $OpenBSD: pgt.c,v 1.95 2019/09/12 12:55:07 stsp Exp $ */
/*
* Copyright (c) 2006 Claudio Jeker <claudio@openbsd.org>
@@ -899,6 +899,7 @@ void
pgt_input_frames(struct pgt_softc *sc, struct mbuf *m)
{
struct ether_header eh;
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
struct ifnet *ifp;
struct ieee80211_channel *chan;
struct ieee80211_rxinfo rxi;
@@ -1022,7 +1023,7 @@ input:
rxi.rxi_flags = 0;
ni->ni_rssi = rxi.rxi_rssi = rssi;
ni->ni_rstamp = rxi.rxi_tstamp = rstamp;
- ieee80211_input(ifp, m, ni, &rxi);
+ ieee80211_inputm(ifp, m, ni, &rxi, &ml);
/*
* The frame may have caused the node to be marked for
* reclamation (e.g. in response to a DEAUTH message)
@@ -1036,6 +1037,7 @@ input:
ifp->if_ierrors++;
}
}
+ if_input(ifp, &ml);
}
void
diff --git a/sys/dev/ic/rt2560.c b/sys/dev/ic/rt2560.c
index c8d85564272..6808304fc20 100644
--- a/sys/dev/ic/rt2560.c
+++ b/sys/dev/ic/rt2560.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rt2560.c,v 1.84 2017/10/26 15:00:28 mpi Exp $ */
+/* $OpenBSD: rt2560.c,v 1.85 2019/09/12 12:55:07 stsp Exp $ */
/*-
* Copyright (c) 2005, 2006
@@ -1076,6 +1076,7 @@ rt2560_prio_intr(struct rt2560_softc *sc)
void
rt2560_decryption_intr(struct rt2560_softc *sc)
{
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = &ic->ic_if;
struct ieee80211_frame *wh;
@@ -1204,7 +1205,7 @@ rt2560_decryption_intr(struct rt2560_softc *sc)
rxi.rxi_flags = 0;
rxi.rxi_rssi = desc->rssi;
rxi.rxi_tstamp = 0; /* unused */
- ieee80211_input(ifp, m, ni, &rxi);
+ ieee80211_inputm(ifp, m, ni, &rxi, &ml);
/* node is no longer needed */
ieee80211_release_node(ic, ni);
@@ -1220,6 +1221,7 @@ skip: desc->flags = htole32(RT2560_RX_BUSY);
sc->rxq.cur_decrypt =
(sc->rxq.cur_decrypt + 1) % RT2560_RX_RING_COUNT;
}
+ if_input(ifp, &ml);
}
/*
diff --git a/sys/dev/ic/rt2661.c b/sys/dev/ic/rt2661.c
index 591115f692d..002e73c389b 100644
--- a/sys/dev/ic/rt2661.c
+++ b/sys/dev/ic/rt2661.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rt2661.c,v 1.94 2017/10/26 15:00:28 mpi Exp $ */
+/* $OpenBSD: rt2661.c,v 1.95 2019/09/12 12:55:07 stsp Exp $ */
/*-
* Copyright (c) 2006
@@ -1153,6 +1153,7 @@ rt2661_tx_dma_intr(struct rt2661_softc *sc, struct rt2661_tx_ring *txq)
void
rt2661_rx_intr(struct rt2661_softc *sc)
{
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = &ic->ic_if;
struct ieee80211_frame *wh;
@@ -1279,7 +1280,7 @@ rt2661_rx_intr(struct rt2661_softc *sc)
rxi.rxi_flags = 0;
rxi.rxi_rssi = desc->rssi;
rxi.rxi_tstamp = 0; /* unused */
- ieee80211_input(ifp, m, ni, &rxi);
+ ieee80211_inputm(ifp, m, ni, &rxi, &ml);
/*-
* Keep track of the average RSSI using an Exponential Moving
@@ -1302,6 +1303,7 @@ skip: desc->flags |= htole32(RT2661_RX_BUSY);
sc->rxq.cur = (sc->rxq.cur + 1) % RT2661_RX_RING_COUNT;
}
+ if_input(ifp, &ml);
}
#ifndef IEEE80211_STA_ONLY
diff --git a/sys/dev/ic/rt2860.c b/sys/dev/ic/rt2860.c
index c6c811c835e..bd82a8480b4 100644
--- a/sys/dev/ic/rt2860.c
+++ b/sys/dev/ic/rt2860.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rt2860.c,v 1.96 2018/10/02 02:05:34 kevlo Exp $ */
+/* $OpenBSD: rt2860.c,v 1.97 2019/09/12 12:55:07 stsp Exp $ */
/*-
* Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
@@ -1260,6 +1260,7 @@ rt2860_maxrssi_chain(struct rt2860_softc *sc, const struct rt2860_rxwi *rxwi)
void
rt2860_rx_intr(struct rt2860_softc *sc)
{
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = &ic->ic_if;
struct ieee80211_frame *wh;
@@ -1419,7 +1420,7 @@ skipbpf:
/* send the frame to the 802.11 layer */
rxi.rxi_rssi = rssi;
rxi.rxi_tstamp = 0; /* unused */
- ieee80211_input(ifp, m, ni, &rxi);
+ ieee80211_inputm(ifp, m, ni, &rxi, &ml);
/* node is no longer needed */
ieee80211_release_node(ic, ni);
@@ -1432,6 +1433,7 @@ skip: rxd->sdl0 &= ~htole16(RT2860_RX_DDONE);
sc->rxq.cur = (sc->rxq.cur + 1) % RT2860_RX_RING_COUNT;
}
+ if_input(ifp, &ml);
/* tell HW what we have processed */
RAL_WRITE(sc, RT2860_RX_CALC_IDX,
diff --git a/sys/dev/ic/rtw.c b/sys/dev/ic/rtw.c
index ce7686c40fa..94cd2e1fa77 100644
--- a/sys/dev/ic/rtw.c
+++ b/sys/dev/ic/rtw.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtw.c,v 1.100 2017/09/22 13:44:00 kevlo Exp $ */
+/* $OpenBSD: rtw.c,v 1.101 2019/09/12 12:55:07 stsp Exp $ */
/* $NetBSD: rtw.c,v 1.29 2004/12/27 19:49:16 dyoung Exp $ */
/*-
@@ -1081,6 +1081,7 @@ rtw_intr_rx(struct rtw_softc *sc, u_int16_t isr)
static const int ratetbl[4] = {2, 4, 11, 22}; /* convert rates:
* hardware -> net80211
*/
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
u_int next, nproc = 0;
int hwrate, len, rate, rssi, sq;
u_int32_t hrssi, hstat, htsfth, htsftl;
@@ -1289,11 +1290,12 @@ rtw_intr_rx(struct rtw_softc *sc, u_int16_t isr)
rxi.rxi_flags = 0;
rxi.rxi_rssi = rssi;
rxi.rxi_tstamp = htsftl;
- ieee80211_input(&sc->sc_if, m, ni, &rxi);
+ ieee80211_inputm(&sc->sc_if, m, ni, &rxi, &ml);
ieee80211_release_node(&sc->sc_ic, ni);
next:
rtw_rxdesc_init(rdb, rs, next, 0);
}
+ if_input(&sc->sc_if, &ml);
rdb->rdb_next = next;
KASSERT(rdb->rdb_next < rdb->rdb_ndesc);
diff --git a/sys/dev/pci/if_ipw.c b/sys/dev/pci/if_ipw.c
index cd0d354d12f..579db1f9780 100644
--- a/sys/dev/pci/if_ipw.c
+++ b/sys/dev/pci/if_ipw.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ipw.c,v 1.123 2019/07/25 01:46:14 cheloha Exp $ */
+/* $OpenBSD: if_ipw.c,v 1.124 2019/09/12 12:55:07 stsp Exp $ */
/*-
* Copyright (c) 2004-2008
@@ -71,7 +71,8 @@ uint16_t ipw_read_prom_word(struct ipw_softc *, uint8_t);
void ipw_command_intr(struct ipw_softc *, struct ipw_soft_buf *);
void ipw_newstate_intr(struct ipw_softc *, struct ipw_soft_buf *);
void ipw_data_intr(struct ipw_softc *, struct ipw_status *,
- struct ipw_soft_bd *, struct ipw_soft_buf *);
+ struct ipw_soft_bd *, struct ipw_soft_buf *,
+ struct mbuf_list *);
void ipw_notification_intr(struct ipw_softc *,
struct ipw_soft_buf *);
void ipw_rx_intr(struct ipw_softc *);
@@ -816,7 +817,7 @@ ipw_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf)
void
ipw_data_intr(struct ipw_softc *sc, struct ipw_status *status,
- struct ipw_soft_bd *sbd, struct ipw_soft_buf *sbuf)
+ struct ipw_soft_bd *sbd, struct ipw_soft_buf *sbuf, struct mbuf_list *ml)
{
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = &ic->ic_if;
@@ -903,7 +904,7 @@ ipw_data_intr(struct ipw_softc *sc, struct ipw_status *status,
rxi.rxi_flags = 0;
rxi.rxi_rssi = status->rssi;
rxi.rxi_tstamp = 0; /* unused */
- ieee80211_input(ifp, m, ni, &rxi);
+ ieee80211_inputm(ifp, m, ni, &rxi, ml);
ieee80211_release_node(ic, ni);
}
@@ -917,6 +918,7 @@ ipw_notification_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf)
void
ipw_rx_intr(struct ipw_softc *sc)
{
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
struct ipw_status *status;
struct ipw_soft_bd *sbd;
struct ipw_soft_buf *sbuf;
@@ -949,7 +951,7 @@ ipw_rx_intr(struct ipw_softc *sc)
case IPW_STATUS_CODE_DATA_802_3:
case IPW_STATUS_CODE_DATA_802_11:
- ipw_data_intr(sc, status, sbd, sbuf);
+ ipw_data_intr(sc, status, sbd, sbuf, &ml);
break;
case IPW_STATUS_CODE_NOTIFICATION:
@@ -966,6 +968,7 @@ ipw_rx_intr(struct ipw_softc *sc)
i * sizeof (struct ipw_bd), sizeof (struct ipw_bd),
BUS_DMASYNC_PREWRITE);
}
+ if_input(&sc->sc_ic.ic_if, &ml);
/* tell the firmware what we have processed */
sc->rxcur = (r == 0) ? IPW_NRBD - 1 : r - 1;
diff --git a/sys/dev/pci/if_iwi.c b/sys/dev/pci/if_iwi.c
index bdb48274251..be8d57baecd 100644
--- a/sys/dev/pci/if_iwi.c
+++ b/sys/dev/pci/if_iwi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_iwi.c,v 1.140 2019/07/25 01:46:14 cheloha Exp $ */
+/* $OpenBSD: if_iwi.c,v 1.141 2019/09/12 12:55:07 stsp Exp $ */
/*-
* Copyright (c) 2004-2008
@@ -87,7 +87,7 @@ int iwi_find_txnode(struct iwi_softc *, const uint8_t *);
int iwi_newstate(struct ieee80211com *, enum ieee80211_state, int);
uint8_t iwi_rate(int);
void iwi_frame_intr(struct iwi_softc *, struct iwi_rx_data *,
- struct iwi_frame *);
+ struct iwi_frame *, struct mbuf_list *);
void iwi_notification_intr(struct iwi_softc *, struct iwi_rx_data *,
struct iwi_notif *);
void iwi_rx_intr(struct iwi_softc *);
@@ -854,7 +854,7 @@ iwi_rate(int plcp)
void
iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_data *data,
- struct iwi_frame *frame)
+ struct iwi_frame *frame, struct mbuf_list *ml)
{
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = &ic->ic_if;
@@ -954,7 +954,7 @@ iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_data *data,
rxi.rxi_flags = 0;
rxi.rxi_rssi = frame->rssi_dbm;
rxi.rxi_tstamp = 0; /* unused */
- ieee80211_input(ifp, m, ni, &rxi);
+ ieee80211_inputm(ifp, m, ni, &rxi, ml);
/* node is no longer needed */
ieee80211_release_node(ic, ni);
@@ -1073,6 +1073,7 @@ iwi_notification_intr(struct iwi_softc *sc, struct iwi_rx_data *data,
void
iwi_rx_intr(struct iwi_softc *sc)
{
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
struct iwi_rx_data *data;
struct iwi_hdr *hdr;
uint32_t hw;
@@ -1090,7 +1091,7 @@ iwi_rx_intr(struct iwi_softc *sc)
switch (hdr->type) {
case IWI_HDR_TYPE_FRAME:
iwi_frame_intr(sc, data,
- (struct iwi_frame *)(hdr + 1));
+ (struct iwi_frame *)(hdr + 1), &ml);
break;
case IWI_HDR_TYPE_NOTIF:
@@ -1105,6 +1106,7 @@ iwi_rx_intr(struct iwi_softc *sc)
sc->rxq.cur = (sc->rxq.cur + 1) % IWI_RX_RING_COUNT;
}
+ if_input(&sc->sc_ic.ic_if, &ml);
/* tell the firmware what we have processed */
hw = (hw == 0) ? IWI_RX_RING_COUNT - 1 : hw - 1;
diff --git a/sys/dev/pci/if_iwm.c b/sys/dev/pci/if_iwm.c
index 0b2116dbc13..20ce2cbe3d2 100644
--- a/sys/dev/pci/if_iwm.c
+++ b/sys/dev/pci/if_iwm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_iwm.c,v 1.249 2019/09/05 16:28:06 stsp Exp $ */
+/* $OpenBSD: if_iwm.c,v 1.250 2019/09/12 12:55:07 stsp Exp $ */
/*
* Copyright (c) 2014, 2016 genua gmbh <info@genua.de>
@@ -368,7 +368,7 @@ void iwm_rx_rx_phy_cmd(struct iwm_softc *, struct iwm_rx_packet *,
struct iwm_rx_data *);
int iwm_get_noise(const struct iwm_statistics_rx_non_phy *);
void iwm_rx_rx_mpdu(struct iwm_softc *, struct iwm_rx_packet *,
- struct iwm_rx_data *);
+ struct iwm_rx_data *, struct mbuf_list *);
void iwm_enable_ht_cck_fallback(struct iwm_softc *, struct iwm_node *);
void iwm_rx_tx_cmd_single(struct iwm_softc *, struct iwm_rx_packet *,
struct iwm_node *);
@@ -3431,7 +3431,7 @@ iwm_get_noise(const struct iwm_statistics_rx_non_phy *stats)
void
iwm_rx_rx_mpdu(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
- struct iwm_rx_data *data)
+ struct iwm_rx_data *data, struct mbuf_list *ml)
{
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_frame *wh;
@@ -3564,9 +3564,9 @@ iwm_rx_rx_mpdu(struct iwm_softc *sc, struct iwm_rx_packet *pkt,
bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN);
}
#endif
- ieee80211_input(IC2IFP(ic), m, ni, &rxi);
+ ieee80211_inputm(IC2IFP(ic), m, ni, &rxi, ml);
/*
- * ieee80211_input() might have changed our BSS.
+ * ieee80211_inputm() might have changed our BSS.
* Restore ic_bss's channel if we are still in the same BSS.
*/
if (ni == ic->ic_bss && IEEE80211_ADDR_EQ(saved_bssid, ni->ni_macaddr))
@@ -7005,6 +7005,7 @@ do { \
void
iwm_notif_intr(struct iwm_softc *sc)
{
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
uint16_t hw;
bus_dmamap_sync(sc->sc_dmat, sc->rxq.stat_dma.map,
@@ -7042,7 +7043,7 @@ iwm_notif_intr(struct iwm_softc *sc)
break;
case IWM_REPLY_RX_MPDU_CMD:
- iwm_rx_rx_mpdu(sc, pkt, data);
+ iwm_rx_rx_mpdu(sc, pkt, data, &ml);
break;
case IWM_TX_CMD:
@@ -7289,6 +7290,7 @@ iwm_notif_intr(struct iwm_softc *sc)
ADVANCE_RXQ(sc);
}
+ if_input(&sc->sc_ic.ic_if, &ml);
/*
* Tell the firmware what we have processed.
diff --git a/sys/dev/pci/if_iwn.c b/sys/dev/pci/if_iwn.c
index d8ab51e393a..553451c0e37 100644
--- a/sys/dev/pci/if_iwn.c
+++ b/sys/dev/pci/if_iwn.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_iwn.c,v 1.215 2019/09/11 08:59:12 stsp Exp $ */
+/* $OpenBSD: if_iwn.c,v 1.216 2019/09/12 12:55:07 stsp Exp $ */
/*-
* Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr>
@@ -156,7 +156,7 @@ int iwn_ccmp_decap(struct iwn_softc *, struct mbuf *,
void iwn_rx_phy(struct iwn_softc *, struct iwn_rx_desc *,
struct iwn_rx_data *);
void iwn_rx_done(struct iwn_softc *, struct iwn_rx_desc *,
- struct iwn_rx_data *);
+ struct iwn_rx_data *, struct mbuf_list *);
void iwn_rx_compressed_ba(struct iwn_softc *, struct iwn_rx_desc *,
struct iwn_rx_data *);
void iwn5000_rx_calib_results(struct iwn_softc *,
@@ -1937,7 +1937,7 @@ iwn_ccmp_decap(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
* Such frames may be received out of order due to
* legitimate retransmissions of failed subframes
* in previous A-MPDUs. Duplicates will be handled
- * in ieee80211_input() as part of A-MPDU reordering.
+ * in ieee80211_inputm() as part of A-MPDU reordering.
*/
} else if (ieee80211_has_seq(wh)) {
/*
@@ -2007,7 +2007,7 @@ iwn_rx_phy(struct iwn_softc *sc, struct iwn_rx_desc *desc,
*/
void
iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
- struct iwn_rx_data *data)
+ struct iwn_rx_data *data, struct mbuf_list *ml)
{
struct iwn_ops *ops = &sc->ops;
struct ieee80211com *ic = &sc->sc_ic;
@@ -2240,7 +2240,7 @@ iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc,
/* Send the frame to the 802.11 layer. */
rxi.rxi_rssi = rssi;
rxi.rxi_tstamp = 0; /* unused */
- ieee80211_input(ifp, m, ni, &rxi);
+ ieee80211_inputm(ifp, m, ni, &rxi, ml);
/* Restore BSS channel. */
if (ni == ic->ic_bss)
@@ -2740,6 +2740,7 @@ iwn_cmd_done(struct iwn_softc *sc, struct iwn_rx_desc *desc)
void
iwn_notif_intr(struct iwn_softc *sc)
{
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
struct iwn_ops *ops = &sc->ops;
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = &ic->ic_if;
@@ -2771,7 +2772,7 @@ iwn_notif_intr(struct iwn_softc *sc)
case IWN_RX_DONE: /* 4965AGN only. */
case IWN_MPDU_RX_DONE:
/* An 802.11 frame has been received. */
- iwn_rx_done(sc, desc, data);
+ iwn_rx_done(sc, desc, data, &ml);
break;
case IWN_RX_COMPRESSED_BA:
/* A Compressed BlockAck has been received. */
@@ -2916,6 +2917,7 @@ iwn_notif_intr(struct iwn_softc *sc)
sc->rxq.cur = (sc->rxq.cur + 1) % IWN_RX_RING_COUNT;
}
+ if_input(&sc->sc_ic.ic_if, &ml);
/* Tell the firmware what we have processed. */
hw = (hw == 0) ? IWN_RX_RING_COUNT - 1 : hw - 1;
diff --git a/sys/dev/pci/if_rtwn.c b/sys/dev/pci/if_rtwn.c
index 2c53aa92524..16340494d45 100644
--- a/sys/dev/pci/if_rtwn.c
+++ b/sys/dev/pci/if_rtwn.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_rtwn.c,v 1.35 2018/10/01 22:36:08 jmatthew Exp $ */
+/* $OpenBSD: if_rtwn.c,v 1.36 2019/09/12 12:55:07 stsp Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
@@ -248,7 +248,8 @@ uint8_t rtwn_pci_read_1(void *, uint16_t);
uint16_t rtwn_pci_read_2(void *, uint16_t);
uint32_t rtwn_pci_read_4(void *, uint16_t);
void rtwn_rx_frame(struct rtwn_pci_softc *,
- struct r92c_rx_desc_pci *, struct rtwn_rx_data *, int);
+ struct r92c_rx_desc_pci *, struct rtwn_rx_data *, int,
+ struct mbuf_list *);
int rtwn_tx(void *, struct mbuf *, struct ieee80211_node *);
void rtwn_tx_done(struct rtwn_pci_softc *, int);
int rtwn_alloc_buffers(void *);
@@ -813,7 +814,7 @@ rtwn_pci_read_4(void *cookie, uint16_t addr)
void
rtwn_rx_frame(struct rtwn_pci_softc *sc, struct r92c_rx_desc_pci *rx_desc,
- struct rtwn_rx_data *rx_data, int desc_idx)
+ struct rtwn_rx_data *rx_data, int desc_idx, struct mbuf_list *ml)
{
struct ieee80211com *ic = &sc->sc_sc.sc_ic;
struct ifnet *ifp = &ic->ic_if;
@@ -974,7 +975,7 @@ rtwn_rx_frame(struct rtwn_pci_softc *sc, struct r92c_rx_desc_pci *rx_desc,
rxi.rxi_flags = 0;
rxi.rxi_rssi = rssi;
rxi.rxi_tstamp = 0; /* Unused. */
- ieee80211_input(ifp, m, ni, &rxi);
+ ieee80211_inputm(ifp, m, ni, &rxi, ml);
/* Node is no longer needed. */
ieee80211_release_node(ic, ni);
}
@@ -1480,6 +1481,7 @@ rtwn_pci_stop(void *cookie)
int
rtwn_88e_intr(struct rtwn_pci_softc *sc)
{
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
u_int32_t status, estatus;
int i;
@@ -1511,6 +1513,8 @@ rtwn_88e_intr(struct rtwn_pci_softc *sc)
rtwn_tx_done(sc, RTWN_VO_QUEUE);
if ((status & (R88E_HIMR_ROK | R88E_HIMR_RDU)) ||
(estatus & R88E_HIMRE_RXFOVW)) {
+ struct ieee80211com *ic = &sc->sc_sc.sc_ic;
+
bus_dmamap_sync(sc->sc_dmat, sc->rx_ring.map, 0,
sizeof(struct r92c_rx_desc_pci) * RTWN_RX_LIST_COUNT,
BUS_DMASYNC_POSTREAD);
@@ -1522,8 +1526,9 @@ rtwn_88e_intr(struct rtwn_pci_softc *sc)
if (letoh32(rx_desc->rxdw0) & R92C_RXDW0_OWN)
continue;
- rtwn_rx_frame(sc, rx_desc, rx_data, i);
+ rtwn_rx_frame(sc, rx_desc, rx_data, i, &ml);
}
+ if_input(&ic->ic_if, &ml);
}
if (status & R88E_HIMR_HSISR_IND_ON_INT) {
@@ -1543,6 +1548,7 @@ int
rtwn_intr(void *xsc)
{
struct rtwn_pci_softc *sc = xsc;
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
u_int32_t status;
int i;
@@ -1561,6 +1567,8 @@ rtwn_intr(void *xsc)
/* Vendor driver treats RX errors like ROK... */
if (status & (R92C_IMR_ROK | R92C_IMR_RXFOVW | R92C_IMR_RDU)) {
+ struct ieee80211com *ic = &sc->sc_sc.sc_ic;
+
bus_dmamap_sync(sc->sc_dmat, sc->rx_ring.map, 0,
sizeof(struct r92c_rx_desc_pci) * RTWN_RX_LIST_COUNT,
BUS_DMASYNC_POSTREAD);
@@ -1572,8 +1580,9 @@ rtwn_intr(void *xsc)
if (letoh32(rx_desc->rxdw0) & R92C_RXDW0_OWN)
continue;
- rtwn_rx_frame(sc, rx_desc, rx_data, i);
+ rtwn_rx_frame(sc, rx_desc, rx_data, i, &ml);
}
+ if_input(&ic->ic_if, &ml);
}
if (status & R92C_IMR_BDOK)
diff --git a/sys/dev/pci/if_wpi.c b/sys/dev/pci/if_wpi.c
index 2a91ccec016..d5f72492c2c 100644
--- a/sys/dev/pci/if_wpi.c
+++ b/sys/dev/pci/if_wpi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_wpi.c,v 1.146 2019/08/27 14:57:48 stsp Exp $ */
+/* $OpenBSD: if_wpi.c,v 1.147 2019/09/12 12:55:07 stsp Exp $ */
/*-
* Copyright (c) 2006-2008
@@ -103,7 +103,7 @@ void wpi_calib_timeout(void *);
int wpi_ccmp_decap(struct wpi_softc *, struct mbuf *,
struct ieee80211_key *);
void wpi_rx_done(struct wpi_softc *, struct wpi_rx_desc *,
- struct wpi_rx_data *);
+ struct wpi_rx_data *, struct mbuf_list *);
void wpi_tx_done(struct wpi_softc *, struct wpi_rx_desc *);
void wpi_cmd_done(struct wpi_softc *, struct wpi_rx_desc *);
void wpi_notif_intr(struct wpi_softc *);
@@ -1180,7 +1180,7 @@ wpi_ccmp_decap(struct wpi_softc *sc, struct mbuf *m, struct ieee80211_key *k)
void
wpi_rx_done(struct wpi_softc *sc, struct wpi_rx_desc *desc,
- struct wpi_rx_data *data)
+ struct wpi_rx_data *data, struct mbuf_list *ml)
{
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = &ic->ic_if;
@@ -1344,7 +1344,7 @@ wpi_rx_done(struct wpi_softc *sc, struct wpi_rx_desc *desc,
/* Send the frame to the 802.11 layer. */
rxi.rxi_rssi = stat->rssi;
rxi.rxi_tstamp = 0; /* unused */
- ieee80211_input(ifp, m, ni, &rxi);
+ ieee80211_inputm(ifp, m, ni, &rxi, ml);
/* Node is no longer needed. */
ieee80211_release_node(ic, ni);
@@ -1412,6 +1412,7 @@ wpi_cmd_done(struct wpi_softc *sc, struct wpi_rx_desc *desc)
void
wpi_notif_intr(struct wpi_softc *sc)
{
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = &ic->ic_if;
uint32_t hw;
@@ -1438,7 +1439,7 @@ wpi_notif_intr(struct wpi_softc *sc)
switch (desc->type) {
case WPI_RX_DONE:
/* An 802.11 frame has been received. */
- wpi_rx_done(sc, desc, data);
+ wpi_rx_done(sc, desc, data, &ml);
break;
case WPI_TX_DONE:
@@ -1527,6 +1528,7 @@ wpi_notif_intr(struct wpi_softc *sc)
sc->rxq.cur = (sc->rxq.cur + 1) % WPI_RX_RING_COUNT;
}
+ if_input(&ic->ic_if, &ml);
/* Tell the firmware what we have processed. */
hw = (hw == 0) ? WPI_RX_RING_COUNT - 1 : hw - 1;
diff --git a/sys/dev/usb/if_athn_usb.c b/sys/dev/usb/if_athn_usb.c
index 39edb129685..83f39f3a748 100644
--- a/sys/dev/usb/if_athn_usb.c
+++ b/sys/dev/usb/if_athn_usb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_athn_usb.c,v 1.52 2018/12/06 07:50:38 stsp Exp $ */
+/* $OpenBSD: if_athn_usb.c,v 1.53 2019/09/12 12:55:07 stsp Exp $ */
/*-
* Copyright (c) 2011 Damien Bergamini <damien.bergamini@free.fr>
@@ -176,7 +176,8 @@ void athn_usb_intr(struct usbd_xfer *, void *,
usbd_status);
void athn_usb_rx_radiotap(struct athn_softc *, struct mbuf *,
struct ar_rx_status *);
-void athn_usb_rx_frame(struct athn_usb_softc *, struct mbuf *);
+void athn_usb_rx_frame(struct athn_usb_softc *, struct mbuf *,
+ struct mbuf_list *);
void athn_usb_rxeof(struct usbd_xfer *, void *,
usbd_status);
void athn_usb_txeof(struct usbd_xfer *, void *,
@@ -1994,7 +1995,8 @@ athn_usb_rx_radiotap(struct athn_softc *sc, struct mbuf *m,
#endif
void
-athn_usb_rx_frame(struct athn_usb_softc *usc, struct mbuf *m)
+athn_usb_rx_frame(struct athn_usb_softc *usc, struct mbuf *m,
+ struct mbuf_list *ml)
{
struct athn_softc *sc = &usc->sc_sc;
struct ieee80211com *ic = &sc->sc_ic;
@@ -2060,7 +2062,7 @@ athn_usb_rx_frame(struct athn_usb_softc *usc, struct mbuf *m)
rxi.rxi_flags = 0;
rxi.rxi_rssi = rs->rs_rssi + AR_USB_DEFAULT_NF;
rxi.rxi_tstamp = betoh64(rs->rs_tstamp);
- ieee80211_input(ifp, m, ni, &rxi);
+ ieee80211_inputm(ifp, m, ni, &rxi, ml);
/* Node is no longer needed. */
ieee80211_release_node(ic, ni);
@@ -2074,6 +2076,7 @@ void
athn_usb_rxeof(struct usbd_xfer *xfer, void *priv,
usbd_status status)
{
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
struct athn_usb_rx_data *data = priv;
struct athn_usb_softc *usc = data->sc;
struct athn_softc *sc = &usc->sc_sc;
@@ -2101,7 +2104,7 @@ athn_usb_rxeof(struct usbd_xfer *xfer, void *priv,
if (__predict_true(stream->m != NULL)) {
memcpy(mtod(stream->m, uint8_t *) +
stream->moff, buf, stream->left);
- athn_usb_rx_frame(usc, stream->m);
+ athn_usb_rx_frame(usc, stream->m, &ml);
stream->m = NULL;
}
/* Next header is 32-bit aligned. */
@@ -2167,7 +2170,7 @@ athn_usb_rxeof(struct usbd_xfer *xfer, void *priv,
if (__predict_true(m != NULL)) {
/* We have all the pktlen bytes in this xfer. */
memcpy(mtod(m, uint8_t *), buf, pktlen);
- athn_usb_rx_frame(usc, m);
+ athn_usb_rx_frame(usc, m, &ml);
}
/* Next header is 32-bit aligned. */
@@ -2175,6 +2178,7 @@ athn_usb_rxeof(struct usbd_xfer *xfer, void *priv,
buf += off;
len -= off;
}
+ if_input(ifp, &ml);
resubmit:
/* Setup a new transfer. */
diff --git a/sys/dev/usb/if_otus.c b/sys/dev/usb/if_otus.c
index cb7e65865ad..86fec55e3ec 100644
--- a/sys/dev/usb/if_otus.c
+++ b/sys/dev/usb/if_otus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_otus.c,v 1.63 2019/01/15 22:08:32 stsp Exp $ */
+/* $OpenBSD: if_otus.c,v 1.64 2019/09/12 12:55:07 stsp Exp $ */
/*-
* Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
@@ -124,7 +124,8 @@ void otus_newassoc(struct ieee80211com *, struct ieee80211_node *,
int);
void otus_intr(struct usbd_xfer *, void *, usbd_status);
void otus_cmd_rxeof(struct otus_softc *, uint8_t *, int);
-void otus_sub_rxeof(struct otus_softc *, uint8_t *, int);
+void otus_sub_rxeof(struct otus_softc *, uint8_t *, int,
+ struct mbuf_list *);
void otus_rxeof(struct usbd_xfer *, void *, usbd_status);
void otus_txeof(struct usbd_xfer *, void *, usbd_status);
int otus_tx(struct otus_softc *, struct mbuf *,
@@ -1064,7 +1065,8 @@ otus_cmd_rxeof(struct otus_softc *sc, uint8_t *buf, int len)
}
void
-otus_sub_rxeof(struct otus_softc *sc, uint8_t *buf, int len)
+otus_sub_rxeof(struct otus_softc *sc, uint8_t *buf, int len,
+ struct mbuf_list *ml)
{
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = &ic->ic_if;
@@ -1195,7 +1197,7 @@ otus_sub_rxeof(struct otus_softc *sc, uint8_t *buf, int len)
rxi.rxi_flags = 0;
rxi.rxi_rssi = tail->rssi;
rxi.rxi_tstamp = 0; /* unused */
- ieee80211_input(ifp, m, ni, &rxi);
+ ieee80211_inputm(ifp, m, ni, &rxi, ml);
/* Node is no longer needed. */
ieee80211_release_node(ic, ni);
@@ -1205,6 +1207,7 @@ otus_sub_rxeof(struct otus_softc *sc, uint8_t *buf, int len)
void
otus_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
{
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
struct otus_rx_data *data = priv;
struct otus_softc *sc = data->sc;
caddr_t buf = data->buf;
@@ -1234,13 +1237,14 @@ otus_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
break;
}
/* Process sub-xfer. */
- otus_sub_rxeof(sc, (uint8_t *)&head[1], hlen);
+ otus_sub_rxeof(sc, (uint8_t *)&head[1], hlen, &ml);
/* Next sub-xfer is aligned on a 32-bit boundary. */
hlen = (sizeof (*head) + hlen + 3) & ~3;
buf += hlen;
len -= hlen;
}
+ if_input(&sc->sc_ic.ic_if, &ml);
resubmit:
usbd_setup_xfer(xfer, sc->data_rx_pipe, data, data->buf, OTUS_RXBUFSZ,
diff --git a/sys/dev/usb/if_rsu.c b/sys/dev/usb/if_rsu.c
index 417666c3503..5e0d0f3ce2e 100644
--- a/sys/dev/usb/if_rsu.c
+++ b/sys/dev/usb/if_rsu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_rsu.c,v 1.44 2019/04/25 01:52:14 kevlo Exp $ */
+/* $OpenBSD: if_rsu.c,v 1.45 2019/09/12 12:55:07 stsp Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
@@ -161,7 +161,8 @@ void rsu_event_join_bss(struct rsu_softc *, uint8_t *, int);
void rsu_rx_event(struct rsu_softc *, uint8_t, uint8_t *, int);
void rsu_rx_multi_event(struct rsu_softc *, uint8_t *, int);
int8_t rsu_get_rssi(struct rsu_softc *, int, void *);
-void rsu_rx_frame(struct rsu_softc *, uint8_t *, int);
+void rsu_rx_frame(struct rsu_softc *, uint8_t *, int,
+ struct mbuf_list *);
void rsu_rx_multi_frame(struct rsu_softc *, uint8_t *, int);
void rsu_rxeof(struct usbd_xfer *, void *, usbd_status);
void rsu_txeof(struct usbd_xfer *, void *, usbd_status);
@@ -1261,7 +1262,8 @@ rsu_get_rssi(struct rsu_softc *sc, int rate, void *physt)
}
void
-rsu_rx_frame(struct rsu_softc *sc, uint8_t *buf, int pktlen)
+rsu_rx_frame(struct rsu_softc *sc, uint8_t *buf, int pktlen,
+ struct mbuf_list *ml)
{
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = &ic->ic_if;
@@ -1371,7 +1373,7 @@ rsu_rx_frame(struct rsu_softc *sc, uint8_t *buf, int pktlen)
rxi.rxi_flags = 0;
rxi.rxi_rssi = rssi;
rxi.rxi_tstamp = 0; /* Unused. */
- ieee80211_input(ifp, m, ni, &rxi);
+ ieee80211_inputm(ifp, m, ni, &rxi, ml);
/* Node is no longer needed. */
ieee80211_release_node(ic, ni);
splx(s);
@@ -1380,6 +1382,7 @@ rsu_rx_frame(struct rsu_softc *sc, uint8_t *buf, int pktlen)
void
rsu_rx_multi_frame(struct rsu_softc *sc, uint8_t *buf, int len)
{
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
struct r92s_rx_stat *stat;
uint32_t rxdw0;
int totlen, pktlen, infosz, npkts;
@@ -1408,13 +1411,14 @@ rsu_rx_multi_frame(struct rsu_softc *sc, uint8_t *buf, int len)
break;
/* Process 802.11 frame. */
- rsu_rx_frame(sc, buf, pktlen);
+ rsu_rx_frame(sc, buf, pktlen, &ml);
/* Next chunk is 128-byte aligned. */
totlen = (totlen + 127) & ~127;
buf += totlen;
len -= totlen;
}
+ if_input(&sc->sc_ic.ic_if, &ml);
}
void
diff --git a/sys/dev/usb/if_run.c b/sys/dev/usb/if_run.c
index fc6ba52f271..5f41c17486f 100644
--- a/sys/dev/usb/if_run.c
+++ b/sys/dev/usb/if_run.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_run.c,v 1.126 2019/04/25 01:52:14 kevlo Exp $ */
+/* $OpenBSD: if_run.c,v 1.127 2019/09/12 12:55:07 stsp Exp $ */
/*-
* Copyright (c) 2008-2010 Damien Bergamini <damien.bergamini@free.fr>
@@ -376,7 +376,8 @@ void run_calibrate_to(void *);
void run_calibrate_cb(struct run_softc *, void *);
void run_newassoc(struct ieee80211com *, struct ieee80211_node *,
int);
-void run_rx_frame(struct run_softc *, uint8_t *, int);
+void run_rx_frame(struct run_softc *, uint8_t *, int,
+ struct mbuf_list *);
void run_rxeof(struct usbd_xfer *, void *, usbd_status);
void run_txeof(struct usbd_xfer *, void *, usbd_status);
int run_tx(struct run_softc *, struct mbuf *,
@@ -2158,7 +2159,8 @@ run_maxrssi_chain(struct run_softc *sc, const struct rt2860_rxwi *rxwi)
}
void
-run_rx_frame(struct run_softc *sc, uint8_t *buf, int dmalen)
+run_rx_frame(struct run_softc *sc, uint8_t *buf, int dmalen,
+ struct mbuf_list *ml)
{
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = &ic->ic_if;
@@ -2295,7 +2297,7 @@ run_rx_frame(struct run_softc *sc, uint8_t *buf, int dmalen)
ni = ieee80211_find_rxnode(ic, wh);
rxi.rxi_rssi = rssi;
rxi.rxi_tstamp = 0; /* unused */
- ieee80211_input(ifp, m, ni, &rxi);
+ ieee80211_inputm(ifp, m, ni, &rxi, ml);
/* node is no longer needed */
ieee80211_release_node(ic, ni);
@@ -2305,6 +2307,7 @@ run_rx_frame(struct run_softc *sc, uint8_t *buf, int dmalen)
void
run_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
{
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
struct run_rx_data *data = priv;
struct run_softc *sc = data->sc;
uint8_t *buf;
@@ -2348,10 +2351,11 @@ run_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
dmalen + 8, xferlen));
break;
}
- run_rx_frame(sc, buf + sizeof (uint32_t), dmalen);
+ run_rx_frame(sc, buf + sizeof (uint32_t), dmalen, &ml);
buf += dmalen + 8;
xferlen -= dmalen + 8;
}
+ if_input(&sc->sc_ic.ic_if, &ml);
skip: /* setup a new transfer */
usbd_setup_xfer(xfer, sc->rxq.pipeh, data, data->buf, RUN_MAX_RXSZ,
diff --git a/sys/dev/usb/if_urtwn.c b/sys/dev/usb/if_urtwn.c
index 96a1ad1a91c..469d65c921b 100644
--- a/sys/dev/usb/if_urtwn.c
+++ b/sys/dev/usb/if_urtwn.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_urtwn.c,v 1.83 2019/03/11 06:19:33 kevlo Exp $ */
+/* $OpenBSD: if_urtwn.c,v 1.84 2019/09/12 12:55:07 stsp Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
@@ -380,7 +380,8 @@ void urtwn_set_key_cb(struct urtwn_softc *, void *);
void urtwn_delete_key(struct ieee80211com *,
struct ieee80211_node *, struct ieee80211_key *);
void urtwn_delete_key_cb(struct urtwn_softc *, void *);
-void urtwn_rx_frame(struct urtwn_softc *, uint8_t *, int);
+void urtwn_rx_frame(struct urtwn_softc *, uint8_t *, int,
+ struct mbuf_list *);
void urtwn_rxeof(struct usbd_xfer *, void *,
usbd_status);
void urtwn_txeof(struct usbd_xfer *, void *,
@@ -1083,7 +1084,8 @@ urtwn_delete_key_cb(struct urtwn_softc *sc, void *arg)
}
void
-urtwn_rx_frame(struct urtwn_softc *sc, uint8_t *buf, int pktlen)
+urtwn_rx_frame(struct urtwn_softc *sc, uint8_t *buf, int pktlen,
+ struct mbuf_list *ml)
{
struct ieee80211com *ic = &sc->sc_sc.sc_ic;
struct ifnet *ifp = &ic->ic_if;
@@ -1194,7 +1196,7 @@ urtwn_rx_frame(struct urtwn_softc *sc, uint8_t *buf, int pktlen)
rxi.rxi_flags = 0;
rxi.rxi_rssi = rssi;
rxi.rxi_tstamp = 0; /* Unused. */
- ieee80211_input(ifp, m, ni, &rxi);
+ ieee80211_inputm(ifp, m, ni, &rxi, ml);
/* Node is no longer needed. */
ieee80211_release_node(ic, ni);
splx(s);
@@ -1204,8 +1206,10 @@ void
urtwn_rxeof(struct usbd_xfer *xfer, void *priv,
usbd_status status)
{
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
struct urtwn_rx_data *data = priv;
struct urtwn_softc *sc = data->sc;
+ struct ieee80211com *ic = &sc->sc_sc.sc_ic;
struct r92c_rx_desc_usb *rxd;
uint32_t rxdw0;
uint8_t *buf;
@@ -1298,13 +1302,14 @@ urtwn_rxeof(struct usbd_xfer *xfer, void *priv,
break;
/* Process 802.11 frame. */
- urtwn_rx_frame(sc, buf, pktlen);
+ urtwn_rx_frame(sc, buf, pktlen, &ml);
/* Handle chunk alignment. */
totlen = (totlen + align) & ~align;
buf += totlen;
len -= totlen;
}
+ if_input(&ic->ic_if, &ml);
resubmit:
/* Setup a new transfer. */
diff --git a/sys/dev/usb/if_zyd.c b/sys/dev/usb/if_zyd.c
index 689ac7e7178..23ea61f7d3f 100644
--- a/sys/dev/usb/if_zyd.c
+++ b/sys/dev/usb/if_zyd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_zyd.c,v 1.120 2019/04/25 01:52:14 kevlo Exp $ */
+/* $OpenBSD: if_zyd.c,v 1.121 2019/09/12 12:55:07 stsp Exp $ */
/*-
* Copyright (c) 2006 by Damien Bergamini <damien.bergamini@free.fr>
@@ -217,7 +217,8 @@ void zyd_set_chan(struct zyd_softc *, struct ieee80211_channel *);
int zyd_set_beacon_interval(struct zyd_softc *, int);
uint8_t zyd_plcp_signal(int);
void zyd_intr(struct usbd_xfer *, void *, usbd_status);
-void zyd_rx_data(struct zyd_softc *, const uint8_t *, uint16_t);
+void zyd_rx_data(struct zyd_softc *, const uint8_t *, uint16_t,
+ struct mbuf_list *);
void zyd_rxeof(struct usbd_xfer *, void *, usbd_status);
void zyd_txeof(struct usbd_xfer *, void *, usbd_status);
int zyd_tx(struct zyd_softc *, struct mbuf *,
@@ -1894,7 +1895,8 @@ zyd_intr(struct usbd_xfer *xfer, void *priv, usbd_status status)
}
void
-zyd_rx_data(struct zyd_softc *sc, const uint8_t *buf, uint16_t len)
+zyd_rx_data(struct zyd_softc *sc, const uint8_t *buf, uint16_t len,
+ struct mbuf_list *ml)
{
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = &ic->ic_if;
@@ -1980,7 +1982,7 @@ zyd_rx_data(struct zyd_softc *sc, const uint8_t *buf, uint16_t len)
rxi.rxi_flags = 0;
rxi.rxi_rssi = stat->rssi;
rxi.rxi_tstamp = 0; /* unused */
- ieee80211_input(ifp, m, ni, &rxi);
+ ieee80211_inputm(ifp, m, ni, &rxi, ml);
/* node is no longer needed */
ieee80211_release_node(ic, ni);
@@ -1991,6 +1993,7 @@ zyd_rx_data(struct zyd_softc *sc, const uint8_t *buf, uint16_t len)
void
zyd_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
{
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
struct zyd_rx_data *data = priv;
struct zyd_softc *sc = data->sc;
struct ieee80211com *ic = &sc->sc_ic;
@@ -2030,15 +2033,16 @@ zyd_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
if (len == 0 || p + len >= end)
break;
- zyd_rx_data(sc, p, len);
+ zyd_rx_data(sc, p, len, &ml);
/* next frame is aligned on a 32-bit boundary */
p += (len + 3) & ~3;
}
} else {
DPRINTFN(3, ("received single-frame transfer\n"));
- zyd_rx_data(sc, data->buf, len);
+ zyd_rx_data(sc, data->buf, len, &ml);
}
+ if_input(ifp, &ml);
skip: /* setup a new transfer */
usbd_setup_xfer(xfer, sc->zyd_ep[ZYD_ENDPT_BIN], data, NULL,
diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c
index 73a9d522950..becb5da6b21 100644
--- a/sys/net80211/ieee80211_input.c
+++ b/sys/net80211/ieee80211_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_input.c,v 1.208 2019/08/29 09:13:56 stsp Exp $ */
+/* $OpenBSD: ieee80211_input.c,v 1.209 2019/09/12 12:55:07 stsp Exp $ */
/*-
* Copyright (c) 2001 Atsushi Onoe
@@ -61,21 +61,22 @@
struct mbuf *ieee80211_defrag(struct ieee80211com *, struct mbuf *, int);
void ieee80211_defrag_timeout(void *);
void ieee80211_input_ba(struct ieee80211com *, struct mbuf *,
- struct ieee80211_node *, int, struct ieee80211_rxinfo *);
+ struct ieee80211_node *, int, struct ieee80211_rxinfo *,
+ struct mbuf_list *);
void ieee80211_input_ba_flush(struct ieee80211com *, struct ieee80211_node *,
- struct ieee80211_rx_ba *);
+ struct ieee80211_rx_ba *, struct mbuf_list *);
void ieee80211_input_ba_gap_timeout(void *arg);
void ieee80211_ba_move_window(struct ieee80211com *,
- struct ieee80211_node *, u_int8_t, u_int16_t);
+ struct ieee80211_node *, u_int8_t, u_int16_t, struct mbuf_list *);
void ieee80211_input_ba_seq(struct ieee80211com *,
- struct ieee80211_node *, uint8_t, uint16_t);
+ struct ieee80211_node *, uint8_t, uint16_t, struct mbuf_list *);
struct mbuf *ieee80211_align_mbuf(struct mbuf *);
void ieee80211_decap(struct ieee80211com *, struct mbuf *,
- struct ieee80211_node *, int);
+ struct ieee80211_node *, int, struct mbuf_list *);
void ieee80211_amsdu_decap(struct ieee80211com *, struct mbuf *,
- struct ieee80211_node *, int);
-void ieee80211_deliver_data(struct ieee80211com *, struct mbuf *,
- struct ieee80211_node *, int);
+ struct ieee80211_node *, int, struct mbuf_list *);
+void ieee80211_enqueue_data(struct ieee80211com *, struct mbuf *,
+ struct ieee80211_node *, int, struct mbuf_list *);
int ieee80211_parse_edca_params_body(struct ieee80211com *,
const u_int8_t *);
int ieee80211_parse_edca_params(struct ieee80211com *, const u_int8_t *);
@@ -155,10 +156,16 @@ ieee80211_get_hdrlen(const struct ieee80211_frame *wh)
* any units so long as values have consistent units and higher values
* mean ``better signal''. The receive timestamp is currently not used
* by the 802.11 layer.
+ *
+ * This function acts on management frames immediately and queues data frames
+ * on the specified mbuf list. Delivery of queued data frames to upper layers
+ * must be triggered with if_input(). Drivers should call if_input() only once
+ * per Rx interrupt to avoid triggering the input ifq pressure drop mechanism
+ * unnecessarily.
*/
void
-ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni,
- struct ieee80211_rxinfo *rxi)
+ieee80211_inputm(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni,
+ struct ieee80211_rxinfo *rxi, struct mbuf_list *ml)
{
struct ieee80211com *ic = (void *)ifp;
struct ieee80211_frame *wh;
@@ -259,7 +266,7 @@ ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni,
(qos & IEEE80211_QOS_ACK_POLICY_MASK) ==
IEEE80211_QOS_ACK_POLICY_NORMAL)) {
/* go through A-MPDU reordering */
- ieee80211_input_ba(ic, m, ni, tid, rxi);
+ ieee80211_input_ba(ic, m, ni, tid, rxi, ml);
return; /* don't free m! */
}
}
@@ -463,9 +470,9 @@ ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni,
if ((ni->ni_flags & IEEE80211_NODE_HT) &&
hasqos && (qos & IEEE80211_QOS_AMSDU))
- ieee80211_amsdu_decap(ic, m, ni, hdrlen);
+ ieee80211_amsdu_decap(ic, m, ni, hdrlen, ml);
else
- ieee80211_decap(ic, m, ni, hdrlen);
+ ieee80211_decap(ic, m, ni, hdrlen, ml);
return;
case IEEE80211_FC0_TYPE_MGT:
@@ -560,6 +567,17 @@ ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni,
}
}
+/* Input handler for drivers which only receive one frame per interrupt. */
+void
+ieee80211_input(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni,
+ struct ieee80211_rxinfo *rxi)
+{
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
+
+ ieee80211_inputm(ifp, m, ni, rxi, &ml);
+ if_input(ifp, &ml);
+}
+
/*
* Handle defragmentation (see 9.5 and Annex C). We support the concurrent
* reception of fragments of three fragmented MSDUs or MMPDUs.
@@ -656,7 +674,8 @@ ieee80211_defrag_timeout(void *arg)
*/
void
ieee80211_input_ba(struct ieee80211com *ic, struct mbuf *m,
- struct ieee80211_node *ni, int tid, struct ieee80211_rxinfo *rxi)
+ struct ieee80211_node *ni, int tid, struct ieee80211_rxinfo *rxi,
+ struct mbuf_list *ml)
{
struct ifnet *ifp = &ic->ic_if;
struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
@@ -699,12 +718,12 @@ ieee80211_input_ba(struct ieee80211com *ic, struct mbuf *m,
ic->ic_stats.is_ht_rx_ba_window_jump++;
ba->ba_winmiss = 0;
ba->ba_missedsn = 0;
- ieee80211_ba_move_window(ic, ni, tid, sn);
+ ieee80211_ba_move_window(ic, ni, tid, sn, ml);
} else {
ic->ic_stats.is_ht_rx_ba_window_slide++;
ieee80211_input_ba_seq(ic, ni, tid,
- (ba->ba_winstart + count) & 0xfff);
- ieee80211_input_ba_flush(ic, ni, ba);
+ (ba->ba_winstart + count) & 0xfff, ml);
+ ieee80211_input_ba_flush(ic, ni, ba, ml);
}
}
/* WinStartB <= SN <= WinEndB */
@@ -730,7 +749,7 @@ ieee80211_input_ba(struct ieee80211com *ic, struct mbuf *m,
else if (timeout_pending(&ba->ba_gap_to))
timeout_del(&ba->ba_gap_to);
- ieee80211_input_ba_flush(ic, ni, ba);
+ ieee80211_input_ba_flush(ic, ni, ba, ml);
}
/*
@@ -739,7 +758,7 @@ ieee80211_input_ba(struct ieee80211com *ic, struct mbuf *m,
*/
void
ieee80211_input_ba_seq(struct ieee80211com *ic, struct ieee80211_node *ni,
- uint8_t tid, uint16_t max_seq)
+ uint8_t tid, uint16_t max_seq, struct mbuf_list *ml)
{
struct ifnet *ifp = &ic->ic_if;
struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
@@ -757,8 +776,8 @@ ieee80211_input_ba_seq(struct ieee80211com *ic, struct ieee80211_node *ni,
IEEE80211_SEQ_SEQ_SHIFT;
if (!SEQ_LT(seq, max_seq))
return;
- ieee80211_input(ifp, ba->ba_buf[ba->ba_head].m,
- ni, &ba->ba_buf[ba->ba_head].rxi);
+ ieee80211_inputm(ifp, ba->ba_buf[ba->ba_head].m,
+ ni, &ba->ba_buf[ba->ba_head].rxi, ml);
ba->ba_buf[ba->ba_head].m = NULL;
} else
ic->ic_stats.is_ht_rx_ba_frame_lost++;
@@ -769,15 +788,15 @@ ieee80211_input_ba_seq(struct ieee80211com *ic, struct ieee80211_node *ni,
/* Flush a consecutive sequence of frames from the reorder buffer. */
void
ieee80211_input_ba_flush(struct ieee80211com *ic, struct ieee80211_node *ni,
- struct ieee80211_rx_ba *ba)
+ struct ieee80211_rx_ba *ba, struct mbuf_list *ml)
{
struct ifnet *ifp = &ic->ic_if;
/* pass reordered MPDUs up to the next MAC process */
while (ba->ba_buf[ba->ba_head].m != NULL) {
- ieee80211_input(ifp, ba->ba_buf[ba->ba_head].m, ni,
- &ba->ba_buf[ba->ba_head].rxi);
+ ieee80211_inputm(ifp, ba->ba_buf[ba->ba_head].m, ni,
+ &ba->ba_buf[ba->ba_head].rxi, ml);
ba->ba_buf[ba->ba_head].m = NULL;
ba->ba_head = (ba->ba_head + 1) % IEEE80211_BA_MAX_WINSZ;
@@ -796,6 +815,7 @@ ieee80211_input_ba_flush(struct ieee80211com *ic, struct ieee80211_node *ni,
void
ieee80211_input_ba_gap_timeout(void *arg)
{
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
struct ieee80211_rx_ba *ba = arg;
struct ieee80211_node *ni = ba->ba_ni;
struct ieee80211com *ic = ni->ni_ic;
@@ -816,7 +836,8 @@ ieee80211_input_ba_gap_timeout(void *arg)
if (skipped > 0)
ba->ba_winend = (ba->ba_winstart + ba->ba_winsize - 1) & 0xfff;
- ieee80211_input_ba_flush(ic, ni, ba);
+ ieee80211_input_ba_flush(ic, ni, ba, &ml);
+ if_input(&ic->ic_if, &ml);
splx(s);
}
@@ -828,7 +849,7 @@ ieee80211_input_ba_gap_timeout(void *arg)
*/
void
ieee80211_ba_move_window(struct ieee80211com *ic, struct ieee80211_node *ni,
- u_int8_t tid, u_int16_t ssn)
+ u_int8_t tid, u_int16_t ssn, struct mbuf_list *ml)
{
struct ifnet *ifp = &ic->ic_if;
struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
@@ -842,8 +863,8 @@ ieee80211_ba_move_window(struct ieee80211com *ic, struct ieee80211_node *ni,
while (count-- > 0) {
/* gaps may exist */
if (ba->ba_buf[ba->ba_head].m != NULL) {
- ieee80211_input(ifp, ba->ba_buf[ba->ba_head].m, ni,
- &ba->ba_buf[ba->ba_head].rxi);
+ ieee80211_inputm(ifp, ba->ba_buf[ba->ba_head].m, ni,
+ &ba->ba_buf[ba->ba_head].rxi, ml);
ba->ba_buf[ba->ba_head].m = NULL;
} else
ic->ic_stats.is_ht_rx_ba_frame_lost++;
@@ -852,12 +873,12 @@ ieee80211_ba_move_window(struct ieee80211com *ic, struct ieee80211_node *ni,
/* move window forward */
ba->ba_winstart = ssn;
- ieee80211_input_ba_flush(ic, ni, ba);
+ ieee80211_input_ba_flush(ic, ni, ba, ml);
}
void
-ieee80211_deliver_data(struct ieee80211com *ic, struct mbuf *m,
- struct ieee80211_node *ni, int mcast)
+ieee80211_enqueue_data(struct ieee80211com *ic, struct mbuf *m,
+ struct ieee80211_node *ni, int mcast, struct mbuf_list *ml)
{
struct ifnet *ifp = &ic->ic_if;
struct ether_header *eh;
@@ -920,16 +941,14 @@ ieee80211_deliver_data(struct ieee80211com *ic, struct mbuf *m,
#endif
ieee80211_eapol_key_input(ic, m, ni);
} else {
- struct mbuf_list ml = MBUF_LIST_INITIALIZER();
- ml_enqueue(&ml, m);
- if_input(ifp, &ml);
+ ml_enqueue(ml, m);
}
}
}
void
ieee80211_decap(struct ieee80211com *ic, struct mbuf *m,
- struct ieee80211_node *ni, int hdrlen)
+ struct ieee80211_node *ni, int hdrlen, struct mbuf_list *ml)
{
struct ether_header eh;
struct ieee80211_frame *wh;
@@ -985,7 +1004,7 @@ ieee80211_decap(struct ieee80211com *ic, struct mbuf *m,
return;
}
}
- ieee80211_deliver_data(ic, m, ni, mcast);
+ ieee80211_enqueue_data(ic, m, ni, mcast, ml);
}
/*
@@ -993,7 +1012,7 @@ ieee80211_decap(struct ieee80211com *ic, struct mbuf *m,
*/
void
ieee80211_amsdu_decap(struct ieee80211com *ic, struct mbuf *m,
- struct ieee80211_node *ni, int hdrlen)
+ struct ieee80211_node *ni, int hdrlen, struct mbuf_list *ml)
{
struct mbuf *n;
struct ether_header *eh;
@@ -1059,7 +1078,7 @@ ieee80211_amsdu_decap(struct ieee80211com *ic, struct mbuf *m,
m_freem(m);
break;
}
- ieee80211_deliver_data(ic, m, ni, mcast);
+ ieee80211_enqueue_data(ic, m, ni, mcast, ml);
if (n->m_pkthdr.len == 0) {
m_freem(n);
@@ -2564,8 +2583,11 @@ ieee80211_recv_addba_req(struct ieee80211com *ic, struct mbuf *m,
return; /* not a PBAC, ignore */
/* PBAC: treat the ADDBA Request like a BlockAckReq */
- if (SEQ_LT(ba->ba_winstart, ssn))
- ieee80211_ba_move_window(ic, ni, tid, ssn);
+ if (SEQ_LT(ba->ba_winstart, ssn)) {
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
+ ieee80211_ba_move_window(ic, ni, tid, ssn, &ml);
+ if_input(&ic->ic_if, &ml);
+ }
return;
}
@@ -3174,6 +3196,9 @@ ieee80211_bar_tid(struct ieee80211com *ic, struct ieee80211_node *ni,
if (ba->ba_timeout_val != 0)
timeout_add_usec(&ba->ba_to, ba->ba_timeout_val);
- if (SEQ_LT(ba->ba_winstart, ssn))
- ieee80211_ba_move_window(ic, ni, tid, ssn);
+ if (SEQ_LT(ba->ba_winstart, ssn)) {
+ struct mbuf_list ml = MBUF_LIST_INITIALIZER();
+ ieee80211_ba_move_window(ic, ni, tid, ssn, &ml);
+ if_input(&ic->ic_if, &ml);
+ }
}
diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h
index e622d35f4dc..7208e5dc0be 100644
--- a/sys/net80211/ieee80211_proto.h
+++ b/sys/net80211/ieee80211_proto.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_proto.h,v 1.45 2019/07/29 10:50:09 stsp Exp $ */
+/* $OpenBSD: ieee80211_proto.h,v 1.46 2019/09/12 12:55:07 stsp Exp $ */
/* $NetBSD: ieee80211_proto.h,v 1.3 2003/10/13 04:23:56 dyoung Exp $ */
/*-
@@ -66,6 +66,9 @@ struct ieee80211_rsnparams;
extern void ieee80211_set_link_state(struct ieee80211com *, int);
extern u_int ieee80211_get_hdrlen(const struct ieee80211_frame *);
extern int ieee80211_classify(struct ieee80211com *, struct mbuf *);
+extern void ieee80211_inputm(struct ifnet *, struct mbuf *,
+ struct ieee80211_node *, struct ieee80211_rxinfo *,
+ struct mbuf_list *);
extern void ieee80211_input(struct ifnet *, struct mbuf *,
struct ieee80211_node *, struct ieee80211_rxinfo *);
extern int ieee80211_output(struct ifnet *, struct mbuf *, struct sockaddr *,