diff options
author | Stefan Sperling <stsp@cvs.openbsd.org> | 2019-09-12 12:55:08 +0000 |
---|---|---|
committer | Stefan Sperling <stsp@cvs.openbsd.org> | 2019-09-12 12:55:08 +0000 |
commit | bf1d600d09a5e6bd03f65236695ceb27eee54583 (patch) | |
tree | 61b19e1ac5df4f2d3e59772380c88bda5b54db33 | |
parent | cdd78b5d4dc581ea298f7e14e7b2403c27de216f (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.c | 14 | ||||
-rw-r--r-- | sys/dev/ic/ar9003.c | 16 | ||||
-rw-r--r-- | sys/dev/ic/ath.c | 9 | ||||
-rw-r--r-- | sys/dev/ic/atw.c | 6 | ||||
-rw-r--r-- | sys/dev/ic/bwi.c | 6 | ||||
-rw-r--r-- | sys/dev/ic/malo.c | 6 | ||||
-rw-r--r-- | sys/dev/ic/pgt.c | 6 | ||||
-rw-r--r-- | sys/dev/ic/rt2560.c | 6 | ||||
-rw-r--r-- | sys/dev/ic/rt2661.c | 6 | ||||
-rw-r--r-- | sys/dev/ic/rt2860.c | 6 | ||||
-rw-r--r-- | sys/dev/ic/rtw.c | 6 | ||||
-rw-r--r-- | sys/dev/pci/if_ipw.c | 13 | ||||
-rw-r--r-- | sys/dev/pci/if_iwi.c | 12 | ||||
-rw-r--r-- | sys/dev/pci/if_iwm.c | 14 | ||||
-rw-r--r-- | sys/dev/pci/if_iwn.c | 14 | ||||
-rw-r--r-- | sys/dev/pci/if_rtwn.c | 21 | ||||
-rw-r--r-- | sys/dev/pci/if_wpi.c | 12 | ||||
-rw-r--r-- | sys/dev/usb/if_athn_usb.c | 16 | ||||
-rw-r--r-- | sys/dev/usb/if_otus.c | 14 | ||||
-rw-r--r-- | sys/dev/usb/if_rsu.c | 14 | ||||
-rw-r--r-- | sys/dev/usb/if_run.c | 14 | ||||
-rw-r--r-- | sys/dev/usb/if_urtwn.c | 15 | ||||
-rw-r--r-- | sys/dev/usb/if_zyd.c | 16 | ||||
-rw-r--r-- | sys/net80211/ieee80211_input.c | 111 | ||||
-rw-r--r-- | sys/net80211/ieee80211_proto.h | 5 |
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 *, |