aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/wpi
diff options
context:
space:
mode:
authorJuli Mallett <jmallett@FreeBSD.org>2009-03-27 03:17:25 +0000
committerJuli Mallett <jmallett@FreeBSD.org>2009-03-27 03:17:25 +0000
commitfcec677d3d53ae09637142c7d81de6b9b98916d8 (patch)
tree6a8a12c37e6cb95bddeb5722de8adeae24c14654 /sys/dev/wpi
parent46b7ac7ad86b94bef71f2debb1f56c5c2ccf1b86 (diff)
downloadsrc-fcec677d3d53ae09637142c7d81de6b9b98916d8.tar.gz
src-fcec677d3d53ae09637142c7d81de6b9b98916d8.zip
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
Notes
Notes: svn path=/head/; revision=190458
Diffstat (limited to 'sys/dev/wpi')
-rw-r--r--sys/dev/wpi/if_wpi.c17
-rw-r--r--sys/dev/wpi/if_wpireg.h2
2 files changed, 15 insertions, 4 deletions
diff --git a/sys/dev/wpi/if_wpi.c b/sys/dev/wpi/if_wpi.c
index 776d089f4506..9f186f86e9de 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 60692a204e0b..2ccc21fedd75 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;