Skip to content

Commit

Permalink
usb: gadget: f_ncm: add SuperSpeed descriptors for CDC NCM
Browse files Browse the repository at this point in the history
Patch enables SuperSpeed for NCM gadget.

Tested with USB3380 and measured TCP throughput with two Intel PCs:
  udc to host: 920 Mbit/s
  host to udc: 550 Mbit/s

Signed-off-by: Jussi Kivilinna <jussi.kivilinna@haltian.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
  • Loading branch information
Jussi Kivilinna authored and Felipe Balbi committed Aug 25, 2016
1 parent 8dc7d30 commit 1650113
Showing 1 changed file with 80 additions and 2 deletions.
82 changes: 80 additions & 2 deletions drivers/usb/gadget/function/f_ncm.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ 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_dualspeed(g) && g->speed == USB_SPEED_HIGH)
if (gadget_is_superspeed(g) && g->speed == USB_SPEED_SUPER)
return 13 * 1024 * 8 * 1000 * 8;
else if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
return 13 * 512 * 8 * 1000 * 8;
else
return 19 * 64 * 1 * 1000 * 8;
Expand Down Expand Up @@ -333,6 +335,76 @@ static struct usb_descriptor_header *ncm_hs_function[] = {
NULL,
};


/* super speed support: */

static struct usb_endpoint_descriptor ss_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 ss_ncm_notify_comp_desc = {
.bLength = sizeof(ss_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 ss_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 ss_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 ss_ncm_bulk_comp_desc = {
.bLength = sizeof(ss_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_ss_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 *) &ss_ncm_notify_desc,
(struct usb_descriptor_header *) &ss_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 *) &ss_ncm_in_desc,
(struct usb_descriptor_header *) &ss_ncm_bulk_comp_desc,
(struct usb_descriptor_header *) &ss_ncm_out_desc,
(struct usb_descriptor_header *) &ss_ncm_bulk_comp_desc,
NULL,
};

/* string descriptors: */

#define STRING_CTRL_IDX 0
Expand Down Expand Up @@ -1431,8 +1503,13 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f)
hs_ncm_notify_desc.bEndpointAddress =
fs_ncm_notify_desc.bEndpointAddress;

ss_ncm_in_desc.bEndpointAddress = fs_ncm_in_desc.bEndpointAddress;
ss_ncm_out_desc.bEndpointAddress = fs_ncm_out_desc.bEndpointAddress;
ss_ncm_notify_desc.bEndpointAddress =
fs_ncm_notify_desc.bEndpointAddress;

status = usb_assign_descriptors(f, ncm_fs_function, ncm_hs_function,
NULL, NULL);
ncm_ss_function, NULL);
if (status)
goto fail;

Expand All @@ -1450,6 +1527,7 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f)
ncm->task_timer.function = ncm_tx_timeout;

DBG(cdev, "CDC Network: %s speed IN/%s OUT/%s NOTIFY/%s\n",
gadget_is_superspeed(c->cdev->gadget) ? "super" :
gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
ncm->port.in_ep->name, ncm->port.out_ep->name,
ncm->notify->name);
Expand Down

0 comments on commit 1650113

Please sign in to comment.