On Tue, Sep 10, 2019 at 07:08:14PM +0200, Matthias Schmidt wrote: > Hi Stefan, > > * Stefan Sperling wrote: > > > > New diff with above changes: > > I tested your new diff with two different systems: > > * Thinkpad T450s with iwm (8265, same as yesterday) > * Thinkpad X220 with iwn (6205) > > and on both systems I see a drastic regression compared to yesterday's > patch. The download speeds is around 400-700K/s on both systems. As > soon as I switch back to the kernel with yesterday's patch, I end up > having 4M/s in average, again.
I think I see why. I forgot to convert some existing ieee80211_input() calls to ieee80211_inputm(), in ieee80211_input.c. These calls are related to buffered aggregated frames, so aggregated frames triggered multiple if_input() calls per interrupt again. In the first diff ieee80211_input() was putting aggregated frames onto the global mbuf list. With this new diff they get added to the mbuf list which the driver's rx interrupt handler passed in. Does this fix the issue? 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 + 884018208fe4e91c192a9925e49a5cc041dd5cac --- sys/net80211/ieee80211_input.c +++ sys/net80211/ieee80211_input.c @@ -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, str (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, 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 +567,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. @@ -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 mbu 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 mbu 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 mbu */ 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_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 /* 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, stru 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, stru 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, stru /* 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 #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 * 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 * */ 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 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, stru 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 ieee 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); + } } 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 *,