Hi,
I recently was asked to interface a Galaxy Nexus with a full-speed USB Ethernet Device utilizes the Galaxy Nexus’s micro-USB OTG port in host mode. I ran into a couple issues in trying to get USB OTG port working with the USB Ethernet devices.
First a little background about the Galaxy Nexus, it utilizes an OMAP 4460 along with a TWL6030 chip that provides the USB OTG capabilities. I unlocked the phone and put a nightly build of Cyanogenmod 9 on the phone which is Andriod 4 ICS with a Linux 3.0.34 kernel running underneath.
The first issue that I experienced after enabling all of the correct drivers in the kernel to support USB Ethernet devices was that when I would trying to send ping packets between the phone (OTG in host mode) and USB Trendnet Ethernet adapter (the phone utilizing the ASIX driver) or the phone (OTG in host mode) and a BeagleBoard –XM (OTG port on the XM in device mode) using the cdc_eem driver, I would experience issues with the sending IP packets over the maximum USB endpoint for either full or high speed (64 bytes or 512 bytes respectively). I kept seeing this syslog message appearing:
"musb_ep_program 831: broken !rx_reinit, ep12 casr a2000"
I traced this issue to the kernel utilizing DMA (the Inventra Highspeed Dual Role Controller). So I disabled DMA with the driver since it is a kernel configuration (CONFIG_MUSB_PIO_ONLY). By doing this it fixed the issue of the getting that error message from appearing in the syslog and all USB Ethernet traffic worked fine while connected via high-speed USB. However, there was an issue with full-speed where the USB port would go down on the phone if I was sending IP packets over the maximum endpoint size (64 bytes). Utilizing a USB analyzer I was able to detect the problem was related to the endpoint sizes being sent by the TWL6030. An example was that if an IP packet was sent with a size of 358 bytes the USB endpoints that were sent would be 256 bytes, 64 bytes and 38 bytes instead of the correct 64, 64, 64, 64, 64, and 38 byte endpoints.
I traced this issue to the musb_host driver in the kernel for when it started a transaction for sending the IP packets it would place 256 bytes onto the TX FIFO for the OTG chip assuming that it could handle bulk splitting of data in the FIFO. However, the chip instead would instead send out all 256 bytes causing an issue with the USB lines and breaking the OTG host port on the phone (kernel panic).
I believe the root cause of this issue to be that the TWL6030 doesn’t support bulk splitting of data while in full speed mode, however, I haven’t been able to confirm this. The reason I say it is because the hack that I had to put into place is as follows:
--- kernel_src_orig/drivers/usb/musb/musb_host.c 2012-06-12 13:31:08.000000000 -0500
+++ kernel_src/drivers/usb/musb/musb_host.c 2012-06-19 08:51:17.000000000 -0500
@@ -786,10 +786,10 @@
qh->type_reg);
}
- if (can_bulk_split(musb, qh->type))
- load_count = min((u32) hw_ep->max_packet_sz_tx,
- len);
- else
+// if (can_bulk_split(musb, qh->type))
+// load_count = min((u32) hw_ep->max_packet_sz_tx,
+// len);
+// else
load_count = min((u32) packet_sz, len);
if (dma_channel && musb_tx_dma_program(dma_controller,
If statement condition can_bulk_split(..) would be true and since the function looks at whether the endpoint connection will support bulk transfer and whether the chip can support bulk split. The endpoint connection is true and the chip says it support bulk split. However, when the driver would write 256 bytes to the TX FIFO and then start the USB transaction the chip sends out all 256 bytes instead of splitting it up into 4 separate transactions (which it should do).
Does anyone else know of experience this issue with TWL-6030 with full-speed USB? I don’t have time to try this on the Pandaboard to confirm my theory since I believe the same chip is on there. Also I wasn’t able to track the registers that MUSB driver is using to either the OMAP or the TWL-6030 to find out whether or not it actually does support what the chip supposedly says it supports.
Thanks,
-Ryan