diff options
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.patch | 119 |
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; |