Index: if_ath_rx_edma.c =================================================================== --- if_ath_rx_edma.c (revision 248985) +++ if_ath_rx_edma.c (working copy) @@ -468,6 +468,7 @@ struct ath_rx_status *rs; int16_t nf; ath_bufhead rxlist; + struct mbuf *m; TAILQ_INIT(&rxlist); @@ -493,11 +494,16 @@ /* Handle the frame */ /* - * Note: this may or may not free bf->bf_m and sync/unmap - * the frame. + * We've been synced already, so unmap. */ +// bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, +// BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap); + rs = &bf->bf_status.ds_rxstat; - if (ath_rx_pkt(sc, rs, bf->bf_rxstatus, tsf, nf, qtype, bf)) + m = bf->bf_m; + bf->bf_m = NULL; + if (ath_rx_pkt(sc, rs, bf->bf_rxstatus, tsf, nf, qtype, bf, m)) ngood++; } Index: if_ath_rx.c =================================================================== --- if_ath_rx.c (revision 248998) +++ if_ath_rx.c (working copy) @@ -502,12 +502,21 @@ } } +/* + * Process a single packet. + * + * The mbuf must already be synced, unmapped and removed from bf->bf_m + * by this stage. + * + * The mbuf must be consumed by this routine - either passed up the + * net80211 stack, put on the holding queue, or freed. + */ int ath_rx_pkt(struct ath_softc *sc, struct ath_rx_status *rs, HAL_STATUS status, - uint64_t tsf, int nf, HAL_RX_QUEUE qtype, struct ath_buf *bf) + uint64_t tsf, int nf, HAL_RX_QUEUE qtype, struct ath_buf *bf, + struct mbuf *m) { struct ath_hal *ah = sc->sc_ah; - struct mbuf *m = bf->bf_m; uint64_t rstamp; int len, type; struct ifnet *ifp = sc->sc_ifp; @@ -548,10 +557,6 @@ /* Process DFS radar events */ if ((rs->rs_phyerr == HAL_PHYERR_RADAR) || (rs->rs_phyerr == HAL_PHYERR_FALSE_RADAR_EXT)) { - /* Since we're touching the frame data, sync it */ - bus_dmamap_sync(sc->sc_dmat, - bf->bf_dmamap, - BUS_DMASYNC_POSTREAD); /* Now pass it to the radar processing code */ ath_dfs_process_phy_err(sc, m, rstamp, rs); } @@ -593,9 +598,6 @@ /* XXX frag's and qos frames */ len = rs->rs_datalen; if (len >= sizeof (struct ieee80211_frame)) { - bus_dmamap_sync(sc->sc_dmat, - bf->bf_dmamap, - BUS_DMASYNC_POSTREAD); ath_handle_micerror(ic, mtod(m, struct ieee80211_frame *), sc->sc_splitmic ? @@ -619,35 +621,20 @@ */ if (ieee80211_radiotap_active(ic) && (rs->rs_status & sc->sc_monpass)) { - bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, - BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap); /* NB: bpf needs the mbuf length setup */ len = rs->rs_datalen; m->m_pkthdr.len = m->m_len = len; - bf->bf_m = NULL; ath_rx_tap(ifp, m, rs, rstamp, nf); #ifdef ATH_ENABLE_RADIOTAP_VENDOR_EXT ath_rx_tap_vendor(ifp, m, rs, rstamp, nf); #endif /* ATH_ENABLE_RADIOTAP_VENDOR_EXT */ ieee80211_radiotap_rx_all(ic, m); - m_freem(m); } /* XXX pass MIC errors up for s/w reclaculation */ + m_freem(m); goto rx_next; } rx_accept: - /* - * Sync and unmap the frame. At this point we're - * committed to passing the mbuf somewhere so clear - * bf_m; this means a new mbuf must be allocated - * when the rx descriptor is setup again to receive - * another frame. - */ - bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap); - bf->bf_m = NULL; - len = rs->rs_datalen; m->m_len = len; @@ -952,7 +939,10 @@ /* * Process a single frame. */ - if (ath_rx_pkt(sc, rs, status, tsf, nf, HAL_RX_QUEUE_HP, bf)) + bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap); + bf->bf_m = NULL; + if (ath_rx_pkt(sc, rs, status, tsf, nf, HAL_RX_QUEUE_HP, bf, m)) ngood++; rx_proc_next: TAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list); Index: if_ath_rx.h =================================================================== --- if_ath_rx.h (revision 248985) +++ if_ath_rx.h (working copy) @@ -58,7 +58,7 @@ extern int ath_rx_pkt(struct ath_softc *sc, struct ath_rx_status *rs, HAL_STATUS status, uint64_t tsf, int nf, HAL_RX_QUEUE qtype, - struct ath_buf *bf); + struct ath_buf *bf, struct mbuf *m); extern void ath_recv_setup_legacy(struct ath_softc *sc);