On Mon, Sep 09, 2019 at 06:17:34PM -0300, Martin Pieuchot wrote: > On 09/09/19(Mon) 16:37, Stefan Sperling wrote: > > On Mon, Sep 09, 2019 at 03:10:04PM +0200, Stefan Sperling wrote: > > > The wifi stack currently calls if_input once per packet instead of once > > > per interrupt. To make the wifi layer play nicely with the network stack > > > we can split ieee80211_input() into two parts: > > > > Updated diff which avoids purging the input queue at every state > > change, e.g. even during SCAN->SCAN. With this we only purge the > > queue if we're leaving RUN state or going back to INIT state. > > Thanks a lot! I must say I looked at this in the past but got lost in > ieee80211_input(). > > Why not keep ieee80211_input() as a wrapper around your new mechanism? > This way you don't need to touch all drivers at once.
We can keep ieee80211_input() for use by drivers that really only deliver one frame per interrupt. Now we don't need to touch some drivers at all. > I'd also suggest using a queue on-stack like we do for Ethernet drivers, > this would get rid of the cleanup of `ic_ml' when the state change. It > would also help developers familiar with Ethernet drivers to understand > what's happening ;o) Yes, thanks for this suggestion! Things make a lot more sense this way. > What about: > > ieee80211_enqueue(ifp, m, ni, &rxi, &ml); > ieee80211_inputm(ifp, &ml); I don't like the name ieee80211_enqueue() because while data frames are being enqueued, management frames are not enqueued. Instead, they cause immediate state changes in the net80211 stack such as allocation of a new node when a beacon is received state changes, e.g. RUN -> AUTH when a deauth frame is received. When drivers have the mbuf list on the stack we do not need a wrapper for if_input() since drivers can just call it directly. So I have chosen to use the following instead: ieee80211_inputm(ifp, m, ni, &rxi, &ml); if_input(ifp, &ml); With ieee80211_input() being a wrapper around these two calls. > Are you sure if_input() needs to be called at splnet()? I don't think > so because many pseudo-drivers call it at a different IPL. I did this only because I was afraid the global ic_ml might be accessed by hardware interrupts while we're running newstate() in a task as some drivers will do. This becomes a non-issue with mbuf lists on the stack. New diff with above changes: diff refs/heads/master refs/heads/ifqdrop blob - d72e8edceada8a680744a6b8478bb91ac9e15e6e blob + a3203d7eb1a67d478bf280a551a43f2dc66c0965 --- sys/dev/ic/ar5008.c +++ sys/dev/ic/ar5008.c @@ -789,7 +789,7 @@ ar5008_rx_radiotap(struct athn_softc *sc, struct mbuf #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 blob - 69ade5ade5a35e632a025db327668d695a0edd2d blob + dafa3bd1f0b4ca2124c6d963c82e289594e88b27 --- sys/dev/ic/ar9003.c +++ sys/dev/ic/ar9003.c @@ -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 #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 blob - c0c5f4241b010c5c38a557d97963fbdbc884336d blob + c4414e5113134012edaf4ce4557bb7e25987e9ef --- sys/dev/ic/ath.c +++ sys/dev/ic/ath.c @@ -1795,6 +1795,7 @@ ath_rxbuf_init(struct ath_softc *sc, struct ath_buf *b 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, @@ -2004,6 +2005,8 @@ ath_rx_proc(void *arg, int npending) rx_next: 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 */ blob - cbf21da74007080c510fa9c56a58aedff62fa586 blob + 6f609b3d8e77c27ba27e6be88cff55fbf87bbb2c --- sys/dev/ic/atw.c +++ sys/dev/ic/atw.c @@ -3029,6 +3029,7 @@ atw_hw_decrypted(struct atw_softc *sc, struct ieee8021 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; blob - 58417ce6f7de644fe86347459c04553956b2edc0 blob + b383588620701ca5c656d29c0384393696914cdc --- sys/dev/ic/bwi.c +++ sys/dev/ic/bwi.c @@ -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, blob - 6a8c5646f0b6f649a60793e127cbd746d8ee89d7 blob + af91b6b414ecc45cd3caceec3f0a7ea6e2aae400 --- sys/dev/ic/malo.c +++ sys/dev/ic/malo.c @@ -1593,6 +1593,7 @@ malo_tx_setup_desc(struct malo_softc *sc, struct malo_ 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); } blob - f44264645097e6f991f5642f7973ed5ebe3e5d7e blob + 695723c6f054b8ab264aefb609696dffbaae6c6b --- sys/dev/ic/pgt.c +++ sys/dev/ic/pgt.c @@ -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 blob - c8d85564272d263215e829d007c11a47741316e6 blob + 4b6e4c0592a9ac543cc83d2ff6ccc692427c0adf --- sys/dev/ic/rt2560.c +++ sys/dev/ic/rt2560.c @@ -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); } /* blob - 591115f692d4f77a522d114e5a91d6026e3452fe blob + 44f767f9bba3aec85758600684dc786d5eab3ed3 --- sys/dev/ic/rt2661.c +++ sys/dev/ic/rt2661.c @@ -1153,6 +1153,7 @@ rt2661_tx_dma_intr(struct rt2661_softc *sc, struct rt2 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 blob - c6c811c835ef4558079c00d50041075b9a8321bb blob + 286f4c859d84a8dc13a54e74c355bc443cf2f7e8 --- sys/dev/ic/rt2860.c +++ sys/dev/ic/rt2860.c @@ -1260,6 +1260,7 @@ rt2860_maxrssi_chain(struct rt2860_softc *sc, const st 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, blob - ce7686c40fa4b1166d0af3fe54d8cad60704f556 blob + 344ffd4381400698d23f8aaee3c623fe649f885f --- sys/dev/ic/rtw.c +++ sys/dev/ic/rtw.c @@ -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); blob - cd0d354d12f45e34327a1d9d2d6ae5b480f9e305 blob + abcd1e0c7f2509e16102d1ea96e245dca587de90 --- sys/dev/pci/if_ipw.c +++ sys/dev/pci/if_ipw.c @@ -71,7 +71,8 @@ uint16_t ipw_read_prom_word(struct ipw_softc *, uint8_ 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_sof 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 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 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; blob - bdb4827425118b9159ae05ad1263bdf5c084254f blob + 84366f6545bde46339adf1da2956b9af8f544469 --- sys/dev/pci/if_iwi.c +++ sys/dev/pci/if_iwi.c @@ -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_dat 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 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; blob - 0b2116dbc13428f1726773000e8e6a8c251d86b4 blob + 26bd730272774dc8cef58c87638c21c0536a016a --- sys/dev/pci/if_iwm.c +++ sys/dev/pci/if_iwm.c @@ -368,7 +368,7 @@ void iwm_rx_rx_phy_cmd(struct iwm_softc *, struct iwm_ 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 * 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_pac 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. blob - 6be794c2cd435c74b1b5c3f028b9613dc74ecf20 blob + c76b53c4c97d6c49f2837667b8758958163246f4 --- sys/dev/pci/if_iwn.c +++ sys/dev/pci/if_iwn.c @@ -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, s * 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 *d */ 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 * /* 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) @@ -2737,6 +2737,7 @@ iwn_cmd_done(struct iwn_softc *sc, struct iwn_rx_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; @@ -2768,7 +2769,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. */ @@ -2913,6 +2914,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; blob - 2c53aa925247b5056360daf479fca12e45624107 blob + 15629e1a07ec75f8eea39d7a629d2d84da6e550e --- sys/dev/pci/if_rtwn.c +++ sys/dev/pci/if_rtwn.c @@ -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_r 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) blob - 2a91ccec016f8047bfe26ede71e8881404fef619 blob + 87f91434312f42404dbb02241eb2d4804ebbdd12 --- sys/dev/pci/if_wpi.c +++ sys/dev/pci/if_wpi.c @@ -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, s 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 * /* 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 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; blob - 39edb129685cac47d29224f18c6f2e7c92922720 blob + 281a19ea8aa92c91869ae177649be9196c947ac3 --- sys/dev/usb/if_athn_usb.c +++ sys/dev/usb/if_athn_usb.c @@ -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 mbu #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 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. */ blob - cb7e65865adb17b86e10bf5c2bc59983a5c8c2c9 blob + 7461c3e57fb2d76faa3c0da0380827a85d19d5f7 --- sys/dev/usb/if_otus.c +++ sys/dev/usb/if_otus.c @@ -124,7 +124,8 @@ void otus_newassoc(struct ieee80211com *, struct ieee 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, in } 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, in 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, in 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_st 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, blob - 417666c3503da89fce1d3dc4301b48376dcf7e41 blob + 71c2c98b878349169107680c071978482dce1678 --- sys/dev/usb/if_rsu.c +++ sys/dev/usb/if_rsu.c @@ -161,7 +161,8 @@ void rsu_event_join_bss(struct rsu_softc *, uint8_t * 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 *phy } 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 p 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 p 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, 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 blob - fc6ba52f271725fe7afbb4abf1a4a1700920a1b4 blob + f22d6d4decb01bab31aa8c0f6fae587651dd3589 --- sys/dev/usb/if_run.c +++ sys/dev/usb/if_run.c @@ -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 r } 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 d 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 d 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_sta 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, blob - 96a1ad1a91c3e98ebc6dece98df6ac277046612c blob + 12fc517090e80d703749a326949aeaaf83617639 --- sys/dev/usb/if_urtwn.c +++ sys/dev/usb/if_urtwn.c @@ -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, i 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. */ blob - 689ac7e7178ca36a091d25cc6f2cf8d15cc45b0b blob + ea8545a4ba48d49eb2830b4e6886613e2e181a7c --- sys/dev/usb/if_zyd.c +++ sys/dev/usb/if_zyd.c @@ -217,7 +217,8 @@ void zyd_set_chan(struct zyd_softc *, struct ieee8021 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_stat } 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, 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, 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_sta 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, blob - 73a9d5229502797c5279734663b1ac1591bec309 blob + 414b0a3419ed9a14e3331fa65a8bbb66a166391e --- sys/net80211/ieee80211_input.c +++ sys/net80211/ieee80211_input.c @@ -71,11 +71,11 @@ void ieee80211_input_ba_seq(struct ieee80211com *, struct ieee80211_node *, uint8_t, uint16_t); 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 +155,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; @@ -463,9 +469,9 @@ ieee80211_input(struct ifnet *ifp, struct mbuf *m, str 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 +566,17 @@ ieee80211_input(struct ifnet *ifp, struct mbuf *m, str } } +/* 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. @@ -856,8 +873,8 @@ ieee80211_ba_move_window(struct ieee80211com *ic, stru } 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 +937,14 @@ ieee80211_deliver_data(struct ieee80211com *ic, struct #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 +1000,7 @@ ieee80211_decap(struct ieee80211com *ic, struct mbuf * return; } } - ieee80211_deliver_data(ic, m, ni, mcast); + ieee80211_enqueue_data(ic, m, ni, mcast, ml); } /* @@ -993,7 +1008,7 @@ ieee80211_decap(struct ieee80211com *ic, struct mbuf * */ 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 +1074,7 @@ ieee80211_amsdu_decap(struct ieee80211com *ic, struct 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); blob - e622d35f4dcd21ea0bb40c6a5d0b3f758e197b38 blob + 52cf8fddfc1658a5c38a4895fff4e858d15bb876 --- sys/net80211/ieee80211_proto.h +++ sys/net80211/ieee80211_proto.h @@ -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 *,