Author: jmallett
Date: Fri Mar 27 03:17:25 2009
New Revision: 190458
URL: http://svn.freebsd.org/changeset/base/190458

Log:
  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

Modified:
  head/sys/dev/wpi/if_wpi.c
  head/sys/dev/wpi/if_wpireg.h

Modified: head/sys/dev/wpi/if_wpi.c
==============================================================================
--- head/sys/dev/wpi/if_wpi.c   Thu Mar 26 22:54:19 2009        (r190457)
+++ head/sys/dev/wpi/if_wpi.c   Fri Mar 27 03:17:25 2009        (r190458)
@@ -1473,6 +1473,20 @@ wpi_rx_intr(struct wpi_softc *sc, struct
            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) {

Modified: head/sys/dev/wpi/if_wpireg.h
==============================================================================
--- head/sys/dev/wpi/if_wpireg.h        Thu Mar 26 22:54:19 2009        
(r190457)
+++ head/sys/dev/wpi/if_wpireg.h        Fri Mar 27 03:17:25 2009        
(r190458)
@@ -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;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to