Skip to content
Oleksij Rempel edited this page Mar 11, 2017 · 12 revisions

Note: we are working in our free time to fix the bugs and extend this driver. Most changes go to new kernel and firmware versions. Please, be kind and make sure you use latest code before sending us bug reports.

Unstable USB connection (ath9k_htc: USB layer deinitialized)

For example:

[ 2081.341801] usb 3-1: USB disconnect, device number 89

[ 2083.284344] ath: phy455: Failed to wakeup in 500us

We get some bug reports about unstable connections and different weird issues. Before reporting a bug, please check:

  • is it working with other (shorter?) cable? This HW seems to be picky about cable quality, so check it.
  • is it working with powered USB hub? People had issues with some specific usb controllers. Test on other HW if possible, or at least find some cheap powered usb hub.
  • is it working with LED disabled? LEDs are triggered from host over USB. Looks like some host controllers don't like it. Use this command:

sudo bash -c "echo none > /sys/class/leds/ath9k_htc-phy*/trigger"

BOGUS urb xfer, pipe 1 != type 3

If you get this error, then you need to update firmware (at least version 1.4) and kernel (at least v3.18). If you still get this issue, ask or check if your kernel really has this patch ath9k_htc: do not use bulk on EP3 and EP4.

... Or, your USB host controller forced this adapter to start in USB 1.1 Full Speed mode. Which is not tested or supported yet.

USB Suspend (Firmware issue)

Currently usb suspend is not working, instead of suspend firmware will reboot. If we are lucky, firmware will set device to lo power mode and reboot on resume.

USB reset (Firmware issue)

Currently usb reset is not correctly working with some usb host controllers.
In some cases it will have absolutely no issue. For example with most xHCI controllers.
On EHCI we can be rebooted:

  • Firmware should do some thing if we get reset interrupt. This will solve reset issue for most EHCI controllers
  • Some EHCI controllers will send suspend signal after reset (Hardware bug?). In this case we should ignore suspend interrupt or find correct way to respond on reset, if FUSB200 support it.

EP4 problem

Description of problem (copy of mail from ath9k-devel list)

It looks like Atheros AR9271, AR7010 (ath9k_htc) and AR9170 (carl9170) have the same usb controller - FUSB200. They share same design and same problem. They have 3 OUT and 1 IN Bulk EPs for network traffic. 1 OUT and 1 IN Interrupt EP for WMI commands.

Here is the layout: https://github.com/qca/open-ath9k-htc-firmware/wiki/usb-regs EP 1 OUT; Bulk; = LP (Low priority downstream); RX0; EP 2 IN; Bulk; = US (upstream) EP 3 IN; Interrupt; EP 4 OUT; Interrupt; EP 5 OUT; Bulk; = HP (High priority downstream); RX1; EP 6 OUT; Bulk; = MP (Medium priority downstream); RX2;

the layout with FIFOs see in attachment.

EPs 5 and 6 are not used by driver. They seems to be supported by hardware, but not handled by firmware. So, not important for now.

EPs 1, 2, 5, 6 are handled by DMA with some previous buffering.

=== And here is the problem ===

EPs 3, 4 accessed directly. For some reasons, response time on this EPs on USB 2.0 is 2-4 ms. Same hardware on USB 3.0 has less delay - 0.2 ms.

=== Test 1. Using Bulk instead of Int ===

Previously ath9k_htc driver had workaround, by forcing Bulk traffic on EP3 and 4. (Actually, only EP4 is interesting for this issue) But it is not working with all hardware correctly. For example, on USB 3.0, the changes well be applied only after device reset. Before device reset, even if ath9k_htc driver was sending Bulk, usb driver converted it back to Interrupt. After reset, usb driver started sending bulk and was not able to work with too small FIFO size on FUSB200. EP4 is mapped to 64byte FIFO, but we need 512 byte for bulk transfer.

According to product brief, FUSB200 can be flexible reconfigurable. Theoretically we should be able to map EP4 to 512 byte FIFO. I tried it, but no interrupt was generated. (some thing is wrong, i do not know what) According to product brief, if FUSB200 connected with DMA module, the FIFOs will be handled by DMA. It looks like FIFOs 0-13 can't be accessed same way like we do it with FIFO14 and 15 (EP3 and EP4). So it looks like we can't fix it correctly - by remaping interrupt EPs to bigger FIFOs and define it as Bulk. If there are some DMA mask registers, please tell me.

=== Test 2. Using other EPs (5, 6 or 1) ===

The DMA engine, which is connected with this EPs, has build in priority system. For example EP1 will need more packets or time until DMA will be triggered. EPs 5 and 6 need less time to react. Maybe we can use this EPs as better workaround. But right now, i do not know how to enable DMA at the beginning. After firmware upload, only EP3 and EP4 are working. Which use no DMA. I was not able to find on which stage and how DMA was enabled. I also have doubt. DMA buffer will probably add too big delay. Espesially on reg read. So, maybe this option wan't work too.

=== Other workarounds ===

Since we can't fix or untill we will be able to fix usb issue, we need to optimise IO operations. Small packets will waste usb bandwidth. For example, typical write or read IO is 8byte. We need at least 64 bytes to normally utilise USB bus.

Here are changes which will increase performance:

  1. do buffered write. - this is was already done before me.
  2. TODO: read arrays. - currently driver will do one read per time.
  3. TODO: optimised and buffered RMW operations.

ath9k use intensively RMW, so it good field for optimisation. RMW is needed to change some bit of register. So we do read + chage + write. By mowing this command to Firmware, we will be able to do buffered RMW and dramatically reduce usb bus traffic.

Here are links to my kernel and firmware branches with described optimisation: https://github.com/olerem/open-ath9k-htc-firmware/commits/speed https://github.com/olerem/linux-2.6/commits/wifi-perf2

With this patches i reduced scan time on ar9271 from 25 to ~15 seconds!

Feedback from Faraday devs

However it looks to me that it's almost identical to the one integrated in FOTG210 (OTG), which has been released to U-Boot open source, and the Linux driver is also available at my github:

FOTG210 driver for U-boot

FOTG210 driver for Linux

Please check its fifo configuration routines, it looks to me that you're encounter issues caused by bad fifo configuration.

Note:

  1. FOTG210_UDC V.S. FUSB200:

    FOTG210 has only 4 fifos, each of it supports upto 512 bytes. FUSB200 has 16 fifos, 0~ 13 support up-to 512 bytes; 14,15 support only up-to 64 bytes.

  2. Faraday USB device controller general design issues:

    1. DO NOT use ISOC!!! It's buggy, you won't want to mess with it.
    2. DO NOT use shared fifo unless you're 100% for sure that there is 1 and only 1 data transfer at a time. (i.e. Mass storage). In other words, the shared fifo is known to be malfunctioned with RNDIS.

and

Is it possible that some FIFOs hard-wired to dma? I can read and write FIFOs 14 and 15 directly without dma, by reading or writing some register. And i also get interrupt if there is some data. But if i map EP4 to FIFO13 instead of FIFO15, then i get no interrupt (I assume FIFO13 and FIFO15 belong to same interrupt group). USB dump shows that data on EP4 was accepted.

Since FIFO14 & FIFO15 supports only upto 64bytes, while others FIFO0 ~ FIFO13 support 512 bytes. So yes, it's possible that FIFO14 & FIFO15 are dedicated for interrupt EPs.