Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 18 Aug 2018 19:39:57 -0700
From:      Adrian Chadd <adrian.chadd@gmail.com>
To:        Farhan Khan <khanzf@gmail.com>
Cc:        "freebsd-wireless@freebsd.org" <freebsd-wireless@freebsd.org>
Subject:   Re: rtwn(4) dropping frames, inconsistently receiving data
Message-ID:  <CAJ-VmomS4LKuyjYPJ8H_9sfj3--zwf2AuSkD2mmgyY5687p0oQ@mail.gmail.com>
In-Reply-To: <81b151d7-203e-b50e-27ad-7dc8ec0a2a2b@gmail.com>
References:  <81b151d7-203e-b50e-27ad-7dc8ec0a2a2b@gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
hi!

ok, hm. So, I wonder if there are some issues with the busdma code. Boot
your test device with say, 1G of memory instead (there's some boot hint you
can set that limits physical memory) which should avoid things like 64 bit
bounce buffer stuff into 32 bit memory space. Booting with 1G hopefully(!)
forces all physical memory below the 32 bit physical address boundary so
you'll be pretty sure the rtwn device can directly access it without having
to go through intermediary bounce buffers that let you have memory live in
64 bit space but then bounce through to 32 bit space via memcpy. Ideally
the descriptor memory would be allocated by busdma and not need bounce
buffers but hey! I make no assumptions.

My guess is that flag is set when it's handed to the firmware and cleared
by the firmware/wifi chip when the descriptor is done. Now, this is good -
it means you're getting frames, so now the fun question is whether it's
something to do with how descriptors are setup, or whether it's how the RX
ring buffer is populated, or the busdma flush/sync stuff above. (There may
be others but I'd start there.) It looks like there's a ring of descriptors
that it's checking so maybe add a routine that dumps out the state of the
ring whenever you get an interrupt so you can see whether any frames in the
ring have been completed.



-adrian



On Sat, 18 Aug 2018 at 19:23, Farhan Khan <khanzf@gmail.com> wrote:

> 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
> _______________________________________________
> freebsd-wireless@freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/freebsd-wireless
> To unsubscribe, send any mail to "freebsd-wireless-unsubscribe@freebsd.org
> "
>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAJ-VmomS4LKuyjYPJ8H_9sfj3--zwf2AuSkD2mmgyY5687p0oQ>