rtwn(4) dropping frames, inconsistently receiving data

Farhan Khan khanzf at gmail.com
Sun Aug 19 02:22:24 UTC 2018


Hi all,

Update and soliciting advice on my efforts to get rtl8188ee on FreeBSD.

High-level summary: The Rx interrupt handler checks the Rx ring to 
determine if it meets a condition prior to running rtwn_pci_rx_frame(). 
If it meets the condition, which I suspect is due to the device not yet 
sending over the data, it will exit rtwn_pci_rx_done() before 
"processing" the frame any further. This results is dropped packets 
and/or data arriving in bursts with long delays between them.

Verbose explanation:

The driver now receives interrupts while in STA mode. This means I see 
nearby APs when I run "ifconfig wlan0 scan". Great! But these APs/beacon 
frames are inconsistently picked up the AP. tcpdump(8) shows busts of 
traffic with large gaps in between. Sometimes a beacon that I see in 
tcpdump(8) does not show up in the scan cache.

Digging deeper, dtrace(1) and printf(1) debugging reveal that:

1. The device is sending interrupts
2. The interrupts are correctly interpreted as Rx, resulting in calling 
rtwn_pci_rx_done()

Here's the problem:

 From here, the Rx interrupt code checks the current Rx ring if the 
"rxdw0" value has the RTWN_RXDW0_OWN bit set. If so, it will break, 
resulting in the frame not being processed. Otherwise, it will run 
rtwn_pci_rx_frame(), which I understand is what processes the frame (ie, 
reads beacon frames, updates the scan cache) and terminates.

See the following code from rtwn_pci_tx.c.

static void
rtwn_pci_rx_done(struct rtwn_softc *sc)
{
         struct rtwn_pci_softc *pc = RTWN_PCI_SOFTC(sc);
         struct rtwn_rx_ring *ring = &pc->rx_ring;

         bus_dmamap_sync(ring->desc_dmat, ring->desc_map, 
BUS_DMASYNC_POSTREAD);
         for (;;) {
                 struct rtwn_rx_stat_pci *rx_desc = &ring->desc[ring->cur];

                 if (le32toh(rx_desc->rxdw0) & RTWN_RXDW0_OWN)
                         break;

                 rtwn_pci_rx_frame(sc, rx_desc, ring->cur);

                 if (!(sc->sc_flags & RTWN_RUNNING))
                         return;

                 ring->cur = (ring->cur + 1) % RTWN_PCI_RX_LIST_COUNT;
         }
}


I noticed that the majority of the time, and specifically when the 
"ifconfig wlan0 scan" fails to return anything, the if-condition just 
above returns true, resulting in the for-loop breaking.

My question is, what does checking the RTWN_RXDW0_OWN bit mean? Why is 
it breaking? Why is data arriving in bursts rather than continuously?

Linux Commentary:
--------
The commentary in the Linux equivalent, _rtl_pci_rx_interrupt located in 
drivers/net/wireless/realtek/rtlwifi/pci.c, suggests that this is 
because the device has not filled out the Rx rings yet:

/* wait data to be filled by hardware */

Later down the comment says:

/* Reaching this point means: data is filled already
...
*/

If this is the case, what needs to happen for the device to send data? 
Why is there a disconnect between the driver interrupt and DMA data? 
What driver-side configuration issues may be causing this?

Ideas? Would hate to be stuck again for a few months :)
Thank you,

--
Farhan Khan
PGP Fingerprint: B28D 2726 E2BC A97E 3854 5ABE 9A9F 00BC D525 16EE


More information about the freebsd-wireless mailing list