diff options
author | Frank Li <Frank.Li@nxp.com> | 2023-05-18 16:49:45 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2023-05-29 15:52:37 +0100 |
commit | 2a1c4639d6d6bcee27f74e38f83ffb43579c4733 (patch) | |
tree | fa5a909c1d73485f3367a6a5f96e87d96df38e67 /drivers/usb/cdns3 | |
parent | bfb46b424652a3396b92ca3c96c169ade9b45b8d (diff) |
usb: cdns3: improve handling of unaligned address case
When the address of a request was not aligned with an 8-byte boundary, the
USB DMA was unable to process it, necessitating the use of an internal
bounce buffer.
In these cases, the request->buf had to be copied to/from this bounce
buffer. However, if this unaligned address scenario arises, it is
unnecessary to perform heavy cache maintenance operations like
usb_gadget_map(unmap)_request_by_dev() on the request->buf, as the DMA
does not utilize it at all. it can be skipped at this case.
iperf3 tests on the rndis case:
Transmit speed (TX): Improved from 299Mbps to 440Mbps
Receive speed (RX): Improved from 290Mbps to 500Mbps
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/r/20230518204947.3770236-1-Frank.Li@nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/cdns3')
-rw-r--r-- | drivers/usb/cdns3/cdns3-gadget.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/drivers/usb/cdns3/cdns3-gadget.c b/drivers/usb/cdns3/cdns3-gadget.c index ccfaebca6faa..d2cedd6db88f 100644 --- a/drivers/usb/cdns3/cdns3-gadget.c +++ b/drivers/usb/cdns3/cdns3-gadget.c @@ -800,7 +800,8 @@ void cdns3_gadget_giveback(struct cdns3_endpoint *priv_ep, if (request->status == -EINPROGRESS) request->status = status; - usb_gadget_unmap_request_by_dev(priv_dev->sysdev, request, + if (likely(!(priv_req->flags & REQUEST_UNALIGNED))) + usb_gadget_unmap_request_by_dev(priv_dev->sysdev, request, priv_ep->dir); if ((priv_req->flags & REQUEST_UNALIGNED) && @@ -2530,10 +2531,12 @@ static int __cdns3_gadget_ep_queue(struct usb_ep *ep, if (ret < 0) return ret; - ret = usb_gadget_map_request_by_dev(priv_dev->sysdev, request, + if (likely(!(priv_req->flags & REQUEST_UNALIGNED))) { + ret = usb_gadget_map_request_by_dev(priv_dev->sysdev, request, usb_endpoint_dir_in(ep->desc)); - if (ret) - return ret; + if (ret) + return ret; + } list_add_tail(&request->list, &priv_ep->deferred_req_list); |