Hi Peter, Peter Chen wrote: > On 21-01-13 18:53:14, Thinh Nguyen wrote: >> If a gadget supports SuperSpeed Plus, then it may operate in different >> sublink speeds. For example, if the gadget supports SuperSpeed Plus >> gen2x2, then it can support 2 sublink speeds gen1 and gen2. Inform the >> host of these speeds in the BOS descriptor. >> > Hi Thinh, > > I read USB 3.2 spec: ch9.6.2.5 SuperSpeedPlus USB Device Capability > > Symmetric. Rx and Tx Sublinks have the same number of lanes and operate > at the same speed. > Asymmetric. Rx and Tx Sublink have different number of lanes and/or > operate at different speeds. > > Why your below cases are all for symmetric, at least, the example 3 > is asymmetric, it has different speed for sublink pairs? > Does your below cases are specification defined or user defined? USB 3.2 spec section 8.5.6.7: Asymmetric lane types are only for SuperSpeed Interchip (SSIC). IMO, It's unlikely that SSIC user will use Linux kernel. We can extend and update the gadget framework if there's any use case for that. > >> Use 1 SSID if the gadget supports up to gen2x1, or not specified: >> - SSID 0 for symmetric RX/TX sublink speed of 10 Gbps. >> >> Use 1 SSID if the gadget supports up to gen1x2: >> - SSID 0 for symmetric RX/TX sublink speed of 5 Gbps. >> >> Use 2 SSIDs if the gadget supports up to gen2x2: >> - SSID 0 for symmetric RX/TX sublink speed of 5 Gbps. > Why SSID 0 is not 10Gbps? SSID 0 and 1 are arbitrary, we can do 0 for 10Gbps. There's no constraint or standard from the USB 3.2 spec. However, you need to set the descriptor wFunctionalitySupport.SSID to be the minimum lane speed SSID it supports. Using SSID 0 makes it easier since we don't have to condition it for multiple SSIDs. >> - SSID 1 for symmetric RX/TX sublink speed of 10 Gbps. > Besides, would you give me an example what kinds of system design > will use below sublink speed? > - SSID 0 for symmetric RX/TX sublink speed of 5 Gbps. > - SSID 1 for symmetric RX/TX sublink speed of 10 Gbps. > > Peter These 2 SSIDs indicate that the device is capable of running in gen1 and gen2 in SSP. Thank you for reviewing it. BR, Thinh > > >> Signed-off-by: Thinh Nguyen <Thinh.Nguyen@xxxxxxxxxxxx> >> --- >> Changes in v6: >> - Rebase on Greg's usb-testing branch >> - Use gadget->max_ssp_rate instead of all the sublink attribute fields (now >> removed) in usb_gadget >> - Use the updated macros >> - Update commit message >> Changes in v5: >> - Rebase on Felipe's testing/next branch >> - Changed Signed-off-by email to match From: email header >> Changes in v4: >> - None >> Changes in v3: >> - None >> Changes in v2: >> - None >> >> drivers/usb/gadget/composite.c | 80 +++++++++++++++++++++++----------- >> 1 file changed, 54 insertions(+), 26 deletions(-) >> >> diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c >> index bc17302a9e85..72a9797dbbae 100644 >> --- a/drivers/usb/gadget/composite.c >> +++ b/drivers/usb/gadget/composite.c >> @@ -735,49 +735,77 @@ static int bos_desc(struct usb_composite_dev *cdev) >> /* The SuperSpeedPlus USB Device Capability descriptor */ >> if (gadget_is_superspeed_plus(cdev->gadget)) { >> struct usb_ssp_cap_descriptor *ssp_cap; >> + u8 ssac = 1; >> + u8 ssic; >> + int i; >> >> - ssp_cap = cdev->req->buf + le16_to_cpu(bos->wTotalLength); >> - bos->bNumDeviceCaps++; >> + if (cdev->gadget->max_ssp_rate == USB_SSP_GEN_2x2) >> + ssac = 3; >> >> /* >> - * Report typical values. >> + * Paired RX and TX sublink speed attributes share >> + * the same SSID. >> */ >> + ssic = (ssac + 1) / 2 - 1; >> >> - le16_add_cpu(&bos->wTotalLength, USB_DT_USB_SSP_CAP_SIZE(1)); >> - ssp_cap->bLength = USB_DT_USB_SSP_CAP_SIZE(1); >> + ssp_cap = cdev->req->buf + le16_to_cpu(bos->wTotalLength); >> + bos->bNumDeviceCaps++; >> + >> + le16_add_cpu(&bos->wTotalLength, USB_DT_USB_SSP_CAP_SIZE(ssac)); >> + ssp_cap->bLength = USB_DT_USB_SSP_CAP_SIZE(ssac); >> ssp_cap->bDescriptorType = USB_DT_DEVICE_CAPABILITY; >> ssp_cap->bDevCapabilityType = USB_SSP_CAP_TYPE; >> ssp_cap->bReserved = 0; >> ssp_cap->wReserved = 0; >> >> ssp_cap->bmAttributes = >> - cpu_to_le32(FIELD_PREP(USB_SSP_SUBLINK_SPEED_ATTRIBS, 1) | >> - FIELD_PREP(USB_SSP_SUBLINK_SPEED_IDS, 0)); >> + cpu_to_le32(FIELD_PREP(USB_SSP_SUBLINK_SPEED_ATTRIBS, ssac) | >> + FIELD_PREP(USB_SSP_SUBLINK_SPEED_IDS, ssic)); >> >> ssp_cap->wFunctionalitySupport = >> cpu_to_le16(FIELD_PREP(USB_SSP_MIN_SUBLINK_SPEED_ATTRIBUTE_ID, 0) | >> FIELD_PREP(USB_SSP_MIN_RX_LANE_COUNT, 1) | >> FIELD_PREP(USB_SSP_MIN_TX_LANE_COUNT, 1)); >> >> - ssp_cap->bmSublinkSpeedAttr[0] = >> - cpu_to_le32(FIELD_PREP(USB_SSP_SUBLINK_SPEED_SSID, 0) | >> - FIELD_PREP(USB_SSP_SUBLINK_SPEED_LSE, >> - USB_SSP_SUBLINK_SPEED_LSE_GBPS) | >> - FIELD_PREP(USB_SSP_SUBLINK_SPEED_ST, >> - USB_SSP_SUBLINK_SPEED_ST_SYM_RX) | >> - FIELD_PREP(USB_SSP_SUBLINK_SPEED_LP, >> - USB_SSP_SUBLINK_SPEED_LP_SSP) | >> - FIELD_PREP(USB_SSP_SUBLINK_SPEED_LSM, 10)); >> - >> - ssp_cap->bmSublinkSpeedAttr[1] = >> - cpu_to_le32(FIELD_PREP(USB_SSP_SUBLINK_SPEED_SSID, 0) | >> - FIELD_PREP(USB_SSP_SUBLINK_SPEED_LSE, >> - USB_SSP_SUBLINK_SPEED_LSE_GBPS) | >> - FIELD_PREP(USB_SSP_SUBLINK_SPEED_ST, >> - USB_SSP_SUBLINK_SPEED_ST_SYM_TX) | >> - FIELD_PREP(USB_SSP_SUBLINK_SPEED_LP, >> - USB_SSP_SUBLINK_SPEED_LP_SSP) | >> - FIELD_PREP(USB_SSP_SUBLINK_SPEED_LSM, 10)); >> + /* >> + * Use 1 SSID if the gadget supports up to gen2x1 or not >> + * specified: >> + * - SSID 0 for symmetric RX/TX sublink speed of 10 Gbps. >> + * >> + * Use 1 SSID if the gadget supports up to gen1x2: >> + * - SSID 0 for symmetric RX/TX sublink speed of 5 Gbps. >> + * >> + * Use 2 SSIDs if the gadget supports up to gen2x2: >> + * - SSID 0 for symmetric RX/TX sublink speed of 5 Gbps. >> + * - SSID 1 for symmetric RX/TX sublink speed of 10 Gbps. >> + */ >> + for (i = 0; i < ssac + 1; i++) { >> + u8 ssid; >> + u8 mantissa; >> + u8 type; >> + >> + ssid = i >> 1; >> + >> + if (cdev->gadget->max_ssp_rate == USB_SSP_GEN_2x1 || >> + cdev->gadget->max_ssp_rate == USB_SSP_GEN_UNKNOWN) >> + mantissa = 10; >> + else >> + mantissa = 5 << ssid; >> + >> + if (i % 2) >> + type = USB_SSP_SUBLINK_SPEED_ST_SYM_TX; >> + else >> + type = USB_SSP_SUBLINK_SPEED_ST_SYM_RX; >> + >> + ssp_cap->bmSublinkSpeedAttr[i] = >> + cpu_to_le32(FIELD_PREP(USB_SSP_SUBLINK_SPEED_SSID, ssid) | >> + FIELD_PREP(USB_SSP_SUBLINK_SPEED_LSE, >> + USB_SSP_SUBLINK_SPEED_LSE_GBPS) | >> + FIELD_PREP(USB_SSP_SUBLINK_SPEED_ST, type) | >> + FIELD_PREP(USB_SSP_SUBLINK_SPEED_LP, >> + USB_SSP_SUBLINK_SPEED_LP_SSP) | >> + FIELD_PREP(USB_SSP_SUBLINK_SPEED_LSM, mantissa)); >> + } >> } >> >> return le16_to_cpu(bos->wTotalLength); >> -- >> 2.28.0 >>