diff options
author | jmallett <jmallett@FreeBSD.org> | 2009-03-27 03:17:25 +0000 |
---|---|---|
committer | jmallett <jmallett@FreeBSD.org> | 2009-03-27 03:17:25 +0000 |
commit | fc9e668b4b28f363d00b9988de356639dd0903ff (patch) | |
tree | 6a8a12c37e6cb95bddeb5722de8adeae24c14654 /sys/dev | |
parent | 49554374b035aa0eebfecbef22e27fdd97177fe8 (diff) | |
download | FreeBSD-src-fc9e668b4b28f363d00b9988de356639dd0903ff.zip FreeBSD-src-fc9e668b4b28f363d00b9988de356639dd0903ff.tar.gz |
o) Check that no overrun or CRC errors were encountered in receiving a
packet. Linux, OpenBSD and our iwn(4) all do this. It also results in
a huge performance improvement (and the rejection of a fair number of
apparently-bad packets on receive) on my hardware.
o) Like the wpi(4) driver in OpenBSD, and like our iwn(4), also drop runt
packets.
o) Don't bother doing IFQ_POLL and then IFQ_DRV_DEQUEUE, just do
IFQ_DRV_DEQUEUE outright. This is more similar to how OpenBSD and our
iwn(4) work.
Reviewed by: sam
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/wpi/if_wpi.c | 17 | ||||
-rw-r--r-- | sys/dev/wpi/if_wpireg.h | 2 |
2 files changed, 15 insertions, 4 deletions
diff --git a/sys/dev/wpi/if_wpi.c b/sys/dev/wpi/if_wpi.c index 776d089..9f186f8 100644 --- a/sys/dev/wpi/if_wpi.c +++ b/sys/dev/wpi/if_wpi.c @@ -1473,6 +1473,20 @@ wpi_rx_intr(struct wpi_softc *sc, struct wpi_rx_desc *desc, le16toh(head->len), (int8_t)stat->rssi, head->rate, head->chan, (uintmax_t)le64toh(tail->tstamp))); + /* discard Rx frames with bad CRC early */ + if ((le32toh(tail->flags) & WPI_RX_NOERROR) != WPI_RX_NOERROR) { + DPRINTFN(WPI_DEBUG_RX, ("%s: rx flags error %x\n", __func__, + le32toh(tail->flags))); + ifp->if_ierrors++; + return; + } + if (le16toh(head->len) < sizeof (struct ieee80211_frame)) { + DPRINTFN(WPI_DEBUG_RX, ("%s: frame too short: %d\n", __func__, + le16toh(head->len))); + ifp->if_ierrors++; + return; + } + /* XXX don't need mbuf, just dma buffer */ mnew = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, MJUMPAGESIZE); if (mnew == NULL) { @@ -2029,7 +2043,7 @@ wpi_start_locked(struct ifnet *ifp) return; for (;;) { - IFQ_POLL(&ifp->if_snd, m); + IFQ_DRV_DEQUEUE(&ifp->if_snd, m); if (m == NULL) break; /* no QoS encapsulation for EAPOL frames */ @@ -2040,7 +2054,6 @@ wpi_start_locked(struct ifnet *ifp) ifp->if_drv_flags |= IFF_DRV_OACTIVE; break; } - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; m = ieee80211_encap(ni, m); if (m == NULL) { diff --git a/sys/dev/wpi/if_wpireg.h b/sys/dev/wpi/if_wpireg.h index 60692a2..2ccc21f 100644 --- a/sys/dev/wpi/if_wpireg.h +++ b/sys/dev/wpi/if_wpireg.h @@ -235,12 +235,10 @@ struct wpi_rx_head { struct wpi_rx_tail { uint32_t flags; -#if 0 #define WPI_RX_NO_CRC_ERR (1 << 0) #define WPI_RX_NO_OVFL_ERR (1 << 1) /* shortcut for the above */ #define WPI_RX_NOERROR (WPI_RX_NO_CRC_ERR | WPI_RX_NO_OVFL_ERR) -#endif uint64_t tstamp; uint32_t tbeacon; } __packed; |