linux-usb.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] usb: gadget: f_ncm: allow using NCM in SuperSpeed Plus gadgets.
@ 2020-08-05  7:58 Lorenzo Colitti
  2020-08-05 10:21 ` Felipe Balbi
  0 siblings, 1 reply; 8+ messages in thread
From: Lorenzo Colitti @ 2020-08-05  7:58 UTC (permalink / raw)
  To: linux-usb; +Cc: balbi, gregkh, zenczykowski, Lorenzo Colitti

Currently, using f_ncm in a SuperSpeed Plus gadget results in
an oops in config_ep_by_speed because ncm_set_alt passes in NULL
ssp_descriptors. Fix this by defining new descriptors for
SuperSpeed Plus. (We cannot re-use the existing definitions for
the SuperSpeed descriptors, even though they are mostly the same,
because they are not fixed initializers).

Also fix reported bandwidth to match bandwidth reported for
SuperSpeed. This calculation is already incorrect, because it
returns 851 Mbps and NCM can already reach speeds in excess of
1.7 Gbps on a 5 Gbps port. But it's better to return 851 Mbps
than 9 Mbps for SuperSpeed Plus.

Tested: enabled f_ncm on a dwc3 gadget and 10Gbps link, ran iperf
Signed-off-by: Lorenzo Colitti <lorenzo@google.com>
---
 drivers/usb/gadget/function/f_ncm.c | 79 ++++++++++++++++++++++++++++-
 1 file changed, 77 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c
index 1d900081b1..91f87165e7 100644
--- a/drivers/usb/gadget/function/f_ncm.c
+++ b/drivers/usb/gadget/function/f_ncm.c
@@ -85,7 +85,8 @@ static inline struct f_ncm *func_to_ncm(struct usb_function *f)
 /* peak (theoretical) bulk transfer rate in bits-per-second */
 static inline unsigned ncm_bitrate(struct usb_gadget *g)
 {
-	if (gadget_is_superspeed(g) && g->speed == USB_SPEED_SUPER)
+	if ((gadget_is_superspeed(g) && g->speed == USB_SPEED_SUPER) ||
+	    (gadget_is_superspeed_plus(g) && g->speed == USB_SPEED_SUPER_PLUS))
 		return 13 * 1024 * 8 * 1000 * 8;
 	else if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
 		return 13 * 512 * 8 * 1000 * 8;
@@ -400,6 +401,75 @@ static struct usb_descriptor_header *ncm_ss_function[] = {
 	NULL,
 };
 
+/* super speed plus support: */
+
+static struct usb_endpoint_descriptor ssp_ncm_notify_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bEndpointAddress =	USB_DIR_IN,
+	.bmAttributes =		USB_ENDPOINT_XFER_INT,
+	.wMaxPacketSize =	cpu_to_le16(NCM_STATUS_BYTECOUNT),
+	.bInterval =		USB_MS_TO_HS_INTERVAL(NCM_STATUS_INTERVAL_MS)
+};
+
+static struct usb_ss_ep_comp_descriptor ssp_ncm_notify_comp_desc = {
+	.bLength =		sizeof(ssp_ncm_notify_comp_desc),
+	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP,
+
+	/* the following 3 values can be tweaked if necessary */
+	/* .bMaxBurst =		0, */
+	/* .bmAttributes =	0, */
+	.wBytesPerInterval =	cpu_to_le16(NCM_STATUS_BYTECOUNT),
+};
+
+static struct usb_endpoint_descriptor ssp_ncm_in_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bEndpointAddress =	USB_DIR_IN,
+	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
+	.wMaxPacketSize =	cpu_to_le16(1024),
+};
+
+static struct usb_endpoint_descriptor ssp_ncm_out_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bEndpointAddress =	USB_DIR_OUT,
+	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
+	.wMaxPacketSize =	cpu_to_le16(1024),
+};
+
+static struct usb_ss_ep_comp_descriptor ssp_ncm_bulk_comp_desc = {
+	.bLength =		sizeof(ssp_ncm_bulk_comp_desc),
+	.bDescriptorType =	USB_DT_SS_ENDPOINT_COMP,
+
+	/* the following 2 values can be tweaked if necessary */
+	/* .bMaxBurst =		0, */
+	/* .bmAttributes =	0, */
+};
+
+static struct usb_descriptor_header *ncm_ssp_function[] = {
+	(struct usb_descriptor_header *) &ncm_iad_desc,
+	/* CDC NCM control descriptors */
+	(struct usb_descriptor_header *) &ncm_control_intf,
+	(struct usb_descriptor_header *) &ncm_header_desc,
+	(struct usb_descriptor_header *) &ncm_union_desc,
+	(struct usb_descriptor_header *) &ecm_desc,
+	(struct usb_descriptor_header *) &ncm_desc,
+	(struct usb_descriptor_header *) &ssp_ncm_notify_desc,
+	(struct usb_descriptor_header *) &ssp_ncm_notify_comp_desc,
+	/* data interface, altsettings 0 and 1 */
+	(struct usb_descriptor_header *) &ncm_data_nop_intf,
+	(struct usb_descriptor_header *) &ncm_data_intf,
+	(struct usb_descriptor_header *) &ssp_ncm_in_desc,
+	(struct usb_descriptor_header *) &ssp_ncm_bulk_comp_desc,
+	(struct usb_descriptor_header *) &ssp_ncm_out_desc,
+	(struct usb_descriptor_header *) &ssp_ncm_bulk_comp_desc,
+	NULL,
+};
+
 /* string descriptors: */
 
 #define STRING_CTRL_IDX	0
@@ -1502,8 +1572,13 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f)
 	ss_ncm_notify_desc.bEndpointAddress =
 		fs_ncm_notify_desc.bEndpointAddress;
 
+	ssp_ncm_in_desc.bEndpointAddress = fs_ncm_in_desc.bEndpointAddress;
+	ssp_ncm_out_desc.bEndpointAddress = fs_ncm_out_desc.bEndpointAddress;
+	ssp_ncm_notify_desc.bEndpointAddress =
+		fs_ncm_notify_desc.bEndpointAddress;
+
 	status = usb_assign_descriptors(f, ncm_fs_function, ncm_hs_function,
-			ncm_ss_function, NULL);
+			ncm_ss_function, ncm_ssp_function);
 	if (status)
 		goto fail;
 
-- 
2.28.0.163.g6104cc2f0b6-goog


^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2020-08-18 17:03 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-08-05  7:58 [PATCH] usb: gadget: f_ncm: allow using NCM in SuperSpeed Plus gadgets Lorenzo Colitti
2020-08-05 10:21 ` Felipe Balbi
2020-08-05 15:49   ` Lorenzo Colitti
2020-08-05 18:04     ` Maciej Żenczykowski
2020-08-17 13:07       ` Felipe Balbi
2020-08-18 17:02       ` Lorenzo Colitti
2020-08-17 13:05     ` Felipe Balbi
2020-08-18 17:03       ` Lorenzo Colitti

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).