somehow splnet was forgotten in the receive path which leads to
the following splassert:

splassert: if_start: want 7 have 5
Starting stack trace...
splassert_check() at splassert_check+0x7e
if_start() at if_start+0x32
ieee80211_deliver_data() at ieee80211_deliver_data+0x1bd
ieee80211_decap() at ieee80211_decap+0xd2
athn_usb_rx_frame() at athn_usb_rx_frame+0x115
athn_usb_rxeof() at athn_usb_rxeof+0xee
usb_transfer_complete() at usb_transfer_complete+0x256
ehci_softintr() at ehci_softintr+0x35
softintr_dispatch() at softintr_dispatch+0x5d
Xsoftnet() at Xsoftnet+0x2d

the following diff fixes that. ok?

Index: if_athn_usb.c
===================================================================
RCS file: /home/cvs/src/sys/dev/usb/if_athn_usb.c,v
retrieving revision 1.9
diff -u -p -u -p -r1.9 if_athn_usb.c
--- if_athn_usb.c       10 Nov 2012 14:35:06 -0000      1.9
+++ if_athn_usb.c       12 Nov 2012 00:38:23 -0000
@@ -1665,6 +1673,7 @@ athn_usb_rx_frame(struct athn_usb_softc 
        struct ar_htc_frame_hdr *htc;
        struct ar_rx_status *rs;
        uint16_t datalen;
+       int s;
 
        if (__predict_false(m->m_len < sizeof(*htc)))
                goto skip;
@@ -1695,6 +1704,8 @@ athn_usb_rx_frame(struct athn_usb_softc 
        m_adj(m, sizeof(*rs));  /* Strip Rx status. */
        m->m_pkthdr.rcvif = ifp;
 
+       s = splnet();
+
        /* Grab a reference to the source node. */
        wh = mtod(m, struct ieee80211_frame *);
        ni = ieee80211_find_rxnode(ic, wh);
@@ -1722,6 +1733,7 @@ athn_usb_rx_frame(struct athn_usb_softc 
 
        /* Node is no longer needed. */
        ieee80211_release_node(ic, ni);
+       splx(s);
        return;
  skip:
        m_freem(m);

Reply via email to