Skip to content

Commit dbe678f

Browse files
nxpfrankligregkh
authored andcommitted
usb: cdns3: fix NCM gadget RX speed 20x slow than expection at iMX8QM
At iMX8QM platform, enable NCM gadget and run 'iperf3 -s'. At host, run 'iperf3 -V -c fe80::6863:98ff:feef:3e0%enxc6e147509498' [ 5] 0.00-1.00 sec 1.55 MBytes 13.0 Mbits/sec 90 4.18 KBytes [ 5] 1.00-2.00 sec 1.44 MBytes 12.0 Mbits/sec 75 4.18 KBytes [ 5] 2.00-3.00 sec 1.48 MBytes 12.4 Mbits/sec 75 4.18 KBytes Expected speed should be bigger than 300Mbits/sec. The root cause of this performance drop was found to be data corruption happening at 4K borders in some Ethernet packets, leading to TCP checksum errors. This corruption occurs from the position (4K - (address & 0x7F)) to 4K. The u_ether function's allocation of skb_buff reserves 64B, meaning all RX addresses resemble 0xXXXX0040. Force trb_burst_size to 16 can fix this problem. Cc: [email protected] Fixes: 7733f6c ("usb: cdns3: Add Cadence USB3 DRD Driver") Signed-off-by: Frank Li <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 7877cb9 commit dbe678f

File tree

1 file changed

+13
-0
lines changed

1 file changed

+13
-0
lines changed

drivers/usb/cdns3/cdns3-gadget.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2097,6 +2097,19 @@ int cdns3_ep_config(struct cdns3_endpoint *priv_ep, bool enable)
20972097
else
20982098
priv_ep->trb_burst_size = 16;
20992099

2100+
/*
2101+
* In versions preceding DEV_VER_V2, for example, iMX8QM, there exit the bugs
2102+
* in the DMA. These bugs occur when the trb_burst_size exceeds 16 and the
2103+
* address is not aligned to 128 Bytes (which is a product of the 64-bit AXI
2104+
* and AXI maximum burst length of 16 or 0xF+1, dma_axi_ctrl0[3:0]). This
2105+
* results in data corruption when it crosses the 4K border. The corruption
2106+
* specifically occurs from the position (4K - (address & 0x7F)) to 4K.
2107+
*
2108+
* So force trb_burst_size to 16 at such platform.
2109+
*/
2110+
if (priv_dev->dev_ver < DEV_VER_V2)
2111+
priv_ep->trb_burst_size = 16;
2112+
21002113
mult = min_t(u8, mult, EP_CFG_MULT_MAX);
21012114
buffering = min_t(u8, buffering, EP_CFG_BUFFERING_MAX);
21022115
maxburst = min_t(u8, maxburst, EP_CFG_MAXBURST_MAX);

0 commit comments

Comments
 (0)