summaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-6.1/950-0469-usb-xhci-add-XHCI_VLI_HUB_TT_QUIRK.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/bcm27xx/patches-6.1/950-0469-usb-xhci-add-XHCI_VLI_HUB_TT_QUIRK.patch')
-rw-r--r--target/linux/bcm27xx/patches-6.1/950-0469-usb-xhci-add-XHCI_VLI_HUB_TT_QUIRK.patch119
1 files changed, 0 insertions, 119 deletions
diff --git a/target/linux/bcm27xx/patches-6.1/950-0469-usb-xhci-add-XHCI_VLI_HUB_TT_QUIRK.patch b/target/linux/bcm27xx/patches-6.1/950-0469-usb-xhci-add-XHCI_VLI_HUB_TT_QUIRK.patch
deleted file mode 100644
index ab0bae587b..0000000000
--- a/target/linux/bcm27xx/patches-6.1/950-0469-usb-xhci-add-XHCI_VLI_HUB_TT_QUIRK.patch
+++ /dev/null
@@ -1,119 +0,0 @@
-From 4f3e85c6f129199a432ef4ed3edbb667a5dedcc1 Mon Sep 17 00:00:00 2001
-From: Jonathan Bell <jonathan@raspberrypi.com>
-Date: Thu, 1 Dec 2022 16:59:44 +0000
-Subject: [PATCH] usb: xhci: add XHCI_VLI_HUB_TT_QUIRK
-
-The integrated USB2.0 hub in the VL805 chipset has a bug where it
-incorrectly determines the remaining available frame time before the
-host next sends a SOF packet with an incremented frame_number.
-
-See the USB2.0 specification sections 11.3 and 11.14.2.3.
-
-The hub's non-periodic TT handler can transmit the IN/OUT handshake
-token too late, so a following 64-byte DATA0/1 packet causes the ACK
-handshake to collide with the propagated SOF. This causes port babble.
-
-Avoid ringing doorbells for vulnerable endpoints during uFrame 7 if the
-TR is Idle to stop one source of babble. An IN transfer for a Running TR
-may happen at any time, so there's not much we can do about that.
-
-Ideally a hub firmware update to properly implement frame timeouts is
-needed, and to avoid spinning for up to 125us when submitting TDs to
-Idle rings.
-
-Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
----
- drivers/usb/host/xhci-pci.c | 1 +
- drivers/usb/host/xhci-ring.c | 46 ++++++++++++++++++++++++++++++++++++
- drivers/usb/host/xhci.h | 1 +
- 3 files changed, 48 insertions(+)
-
---- a/drivers/usb/host/xhci-pci.c
-+++ b/drivers/usb/host/xhci-pci.c
-@@ -298,6 +298,7 @@ static void xhci_pci_quirks(struct devic
- xhci->quirks |= XHCI_AVOID_DQ_ON_LINK;
- xhci->quirks |= XHCI_VLI_TRB_CACHE_BUG;
- xhci->quirks |= XHCI_VLI_SS_BULK_OUT_BUG;
-+ xhci->quirks |= XHCI_VLI_HUB_TT_QUIRK;
- }
-
- if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
---- a/drivers/usb/host/xhci-ring.c
-+++ b/drivers/usb/host/xhci-ring.c
-@@ -3583,6 +3583,48 @@ static int xhci_align_td(struct xhci_hcd
- return 1;
- }
-
-+static void xhci_vl805_hub_tt_quirk(struct xhci_hcd *xhci, struct urb *urb,
-+ struct xhci_ring *ring)
-+{
-+ struct list_head *tmp;
-+ struct usb_device *udev = urb->dev;
-+ unsigned int timeout = 0;
-+ unsigned int single_td = 0;
-+
-+ /*
-+ * Adding a TD to an Idle ring for a FS nonperiodic endpoint
-+ * that is behind the internal hub's TT will run the risk of causing a
-+ * downstream port babble if submitted late in uFrame 7.
-+ * Wait until we've moved on into at least uFrame 0
-+ * (MFINDEX references the next SOF to be transmitted).
-+ *
-+ * Rings for IN endpoints in the Running state also risk causing
-+ * babble if the returned data is large, but there's not much we can do
-+ * about it here.
-+ */
-+ if (udev->route & 0xffff0 || udev->speed != USB_SPEED_FULL)
-+ return;
-+
-+ list_for_each(tmp, &ring->td_list) {
-+ single_td++;
-+ if (single_td == 2) {
-+ single_td = 0;
-+ break;
-+ }
-+ }
-+ if (single_td) {
-+ while (timeout < 20 &&
-+ (readl(&xhci->run_regs->microframe_index) & 0x7) == 0) {
-+ udelay(10);
-+ timeout++;
-+ }
-+ if (timeout >= 20)
-+ xhci_warn(xhci, "MFINDEX didn't advance - %u.%u dodged\n",
-+ readl(&xhci->run_regs->microframe_index) >> 3,
-+ readl(&xhci->run_regs->microframe_index) & 7);
-+ }
-+}
-+
- /* This is very similar to what ehci-q.c qtd_fill() does */
- int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
- struct urb *urb, int slot_id, unsigned int ep_index)
-@@ -3751,6 +3793,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
- }
-
- check_trb_math(urb, enqd_len);
-+ if (xhci->quirks & XHCI_VLI_HUB_TT_QUIRK)
-+ xhci_vl805_hub_tt_quirk(xhci, urb, ring);
- giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id,
- start_cycle, start_trb);
- return 0;
-@@ -3886,6 +3930,8 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *
- /* Event on completion */
- field | TRB_IOC | TRB_TYPE(TRB_STATUS) | ep_ring->cycle_state);
-
-+ if (xhci->quirks & XHCI_VLI_HUB_TT_QUIRK)
-+ xhci_vl805_hub_tt_quirk(xhci, urb, ep_ring);
- giveback_first_trb(xhci, slot_id, ep_index, 0,
- start_cycle, start_trb);
- return 0;
---- a/drivers/usb/host/xhci.h
-+++ b/drivers/usb/host/xhci.h
-@@ -1911,6 +1911,7 @@ struct xhci_hcd {
- #define XHCI_AVOID_DQ_ON_LINK BIT_ULL(47)
- #define XHCI_VLI_TRB_CACHE_BUG BIT_ULL(48)
- #define XHCI_VLI_SS_BULK_OUT_BUG BIT_ULL(49)
-+#define XHCI_VLI_HUB_TT_QUIRK BIT_ULL(50)
-
- unsigned int num_active_eps;
- unsigned int limit_active_eps;