Date: Sat, 18 Aug 2018 22:22:22 -0400 From: Farhan Khan <khanzf@gmail.com> To: freebsd-wireless@freebsd.org Subject: rtwn(4) dropping frames, inconsistently receiving data Message-ID: <81b151d7-203e-b50e-27ad-7dc8ec0a2a2b@gmail.com>
next in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?81b151d7-203e-b50e-27ad-7dc8ec0a2a2b>