mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
xhci: set missing SuperSpeedPlus Link Protocol bit in roothub descriptor
commit 7bea22b124 upstream.
A SuperSpeedPlus roothub needs to have the Link Protocol (LP) bit set in
the bmSublinkSpeedAttr[] entry of a SuperSpeedPlus descriptor.
If the xhci controller has an optional Protocol Speed ID (PSI) table then
that will be used as a base to create the roothub SuperSpeedPlus
descriptor.
The PSI table does not however necessary contain the LP bit so we need
to set it manually.
Check the psi speed and set LP bit if speed is 10Gbps or higher.
We're not setting it for 5 to 10Gbps as USB 3.1 specification always
mention SuperSpeedPlus for 10Gbps or higher, and some SSIC USB 3.0 speeds
can be over 5Gbps, such as SSIC-G3B-L1 at 5830 Mbps
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
f1a04773d7
commit
f77615db8a
@@ -112,7 +112,7 @@ static int xhci_create_usb3_bos_desc(struct xhci_hcd *xhci, char *buf,
|
||||
|
||||
/* If PSI table exists, add the custom speed attributes from it */
|
||||
if (usb3_1 && xhci->usb3_rhub.psi_count) {
|
||||
u32 ssp_cap_base, bm_attrib, psi;
|
||||
u32 ssp_cap_base, bm_attrib, psi, psi_mant, psi_exp;
|
||||
int offset;
|
||||
|
||||
ssp_cap_base = USB_DT_BOS_SIZE + USB_DT_USB_SS_CAP_SIZE;
|
||||
@@ -139,6 +139,15 @@ static int xhci_create_usb3_bos_desc(struct xhci_hcd *xhci, char *buf,
|
||||
for (i = 0; i < xhci->usb3_rhub.psi_count; i++) {
|
||||
psi = xhci->usb3_rhub.psi[i];
|
||||
psi &= ~USB_SSP_SUBLINK_SPEED_RSVD;
|
||||
psi_exp = XHCI_EXT_PORT_PSIE(psi);
|
||||
psi_mant = XHCI_EXT_PORT_PSIM(psi);
|
||||
|
||||
/* Shift to Gbps and set SSP Link BIT(14) if 10Gpbs */
|
||||
for (; psi_exp < 3; psi_exp++)
|
||||
psi_mant /= 1000;
|
||||
if (psi_mant >= 10)
|
||||
psi |= BIT(14);
|
||||
|
||||
if ((psi & PLT_MASK) == PLT_SYM) {
|
||||
/* Symmetric, create SSA RX and TX from one PSI entry */
|
||||
put_unaligned_le32(psi, &buf[offset]);
|
||||
|
||||
Reference in New Issue
Block a user