aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Zimmerman <Paul.Zimmerman@synopsys.com>2011-06-27 17:13:18 -0400
committerFelipe Balbi <balbi@ti.com>2011-07-08 06:55:30 -0400
commit04617db7aa688598ebd3fce20691d31a5e778b45 (patch)
tree101ac8a5892c1fb6e9aefe2a4acffc666ace3089
parent96fe53ef5498ba130b2f054f2de38e090ddaa55f (diff)
usb: gadget: add SS descriptors to Ethernet gadget
Add SuperSpeed descriptors to the Network USB function drivers. This has been lightly tested using a Linux host. I was able to ssh from device to host and host to device, no obvious problems seen. Signed-off-by: Paul Zimmerman <paulz@synopsys.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
-rw-r--r--drivers/usb/gadget/ether.c2
-rw-r--r--drivers/usb/gadget/f_ecm.c100
-rw-r--r--drivers/usb/gadget/f_eem.c56
-rw-r--r--drivers/usb/gadget/f_rndis.c101
-rw-r--r--drivers/usb/gadget/f_subset.c64
-rw-r--r--drivers/usb/gadget/u_ether.c12
6 files changed, 324 insertions, 11 deletions
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index ac41858800a5..aafc84f33e26 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -401,7 +401,7 @@ static struct usb_composite_driver eth_driver = {
401 .name = "g_ether", 401 .name = "g_ether",
402 .dev = &device_desc, 402 .dev = &device_desc,
403 .strings = dev_strings, 403 .strings = dev_strings,
404 .max_speed = USB_SPEED_HIGH, 404 .max_speed = USB_SPEED_SUPER,
405 .unbind = __exit_p(eth_unbind), 405 .unbind = __exit_p(eth_unbind),
406}; 406};
407 407
diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c
index ddedbc83bc37..3691a0cb9465 100644
--- a/drivers/usb/gadget/f_ecm.c
+++ b/drivers/usb/gadget/f_ecm.c
@@ -77,10 +77,12 @@ static inline struct f_ecm *func_to_ecm(struct usb_function *f)
77/* peak (theoretical) bulk transfer rate in bits-per-second */ 77/* peak (theoretical) bulk transfer rate in bits-per-second */
78static inline unsigned ecm_bitrate(struct usb_gadget *g) 78static inline unsigned ecm_bitrate(struct usb_gadget *g)
79{ 79{
80 if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) 80 if (gadget_is_superspeed(g) && g->speed == USB_SPEED_SUPER)
81 return 13 * 1024 * 8 * 1000 * 8;
82 else if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
81 return 13 * 512 * 8 * 1000 * 8; 83 return 13 * 512 * 8 * 1000 * 8;
82 else 84 else
83 return 19 * 64 * 1 * 1000 * 8; 85 return 19 * 64 * 1 * 1000 * 8;
84} 86}
85 87
86/*-------------------------------------------------------------------------*/ 88/*-------------------------------------------------------------------------*/
@@ -210,8 +212,10 @@ static struct usb_descriptor_header *ecm_fs_function[] = {
210 (struct usb_descriptor_header *) &ecm_header_desc, 212 (struct usb_descriptor_header *) &ecm_header_desc,
211 (struct usb_descriptor_header *) &ecm_union_desc, 213 (struct usb_descriptor_header *) &ecm_union_desc,
212 (struct usb_descriptor_header *) &ecm_desc, 214 (struct usb_descriptor_header *) &ecm_desc,
215
213 /* NOTE: status endpoint might need to be removed */ 216 /* NOTE: status endpoint might need to be removed */
214 (struct usb_descriptor_header *) &fs_ecm_notify_desc, 217 (struct usb_descriptor_header *) &fs_ecm_notify_desc,
218
215 /* data interface, altsettings 0 and 1 */ 219 /* data interface, altsettings 0 and 1 */
216 (struct usb_descriptor_header *) &ecm_data_nop_intf, 220 (struct usb_descriptor_header *) &ecm_data_nop_intf,
217 (struct usb_descriptor_header *) &ecm_data_intf, 221 (struct usb_descriptor_header *) &ecm_data_intf,
@@ -231,6 +235,7 @@ static struct usb_endpoint_descriptor hs_ecm_notify_desc = {
231 .wMaxPacketSize = cpu_to_le16(ECM_STATUS_BYTECOUNT), 235 .wMaxPacketSize = cpu_to_le16(ECM_STATUS_BYTECOUNT),
232 .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4, 236 .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
233}; 237};
238
234static struct usb_endpoint_descriptor hs_ecm_in_desc = { 239static struct usb_endpoint_descriptor hs_ecm_in_desc = {
235 .bLength = USB_DT_ENDPOINT_SIZE, 240 .bLength = USB_DT_ENDPOINT_SIZE,
236 .bDescriptorType = USB_DT_ENDPOINT, 241 .bDescriptorType = USB_DT_ENDPOINT,
@@ -255,8 +260,10 @@ static struct usb_descriptor_header *ecm_hs_function[] = {
255 (struct usb_descriptor_header *) &ecm_header_desc, 260 (struct usb_descriptor_header *) &ecm_header_desc,
256 (struct usb_descriptor_header *) &ecm_union_desc, 261 (struct usb_descriptor_header *) &ecm_union_desc,
257 (struct usb_descriptor_header *) &ecm_desc, 262 (struct usb_descriptor_header *) &ecm_desc,
263
258 /* NOTE: status endpoint might need to be removed */ 264 /* NOTE: status endpoint might need to be removed */
259 (struct usb_descriptor_header *) &hs_ecm_notify_desc, 265 (struct usb_descriptor_header *) &hs_ecm_notify_desc,
266
260 /* data interface, altsettings 0 and 1 */ 267 /* data interface, altsettings 0 and 1 */
261 (struct usb_descriptor_header *) &ecm_data_nop_intf, 268 (struct usb_descriptor_header *) &ecm_data_nop_intf,
262 (struct usb_descriptor_header *) &ecm_data_intf, 269 (struct usb_descriptor_header *) &ecm_data_intf,
@@ -265,6 +272,76 @@ static struct usb_descriptor_header *ecm_hs_function[] = {
265 NULL, 272 NULL,
266}; 273};
267 274
275/* super speed support: */
276
277static struct usb_endpoint_descriptor ss_ecm_notify_desc = {
278 .bLength = USB_DT_ENDPOINT_SIZE,
279 .bDescriptorType = USB_DT_ENDPOINT,
280
281 .bEndpointAddress = USB_DIR_IN,
282 .bmAttributes = USB_ENDPOINT_XFER_INT,
283 .wMaxPacketSize = cpu_to_le16(ECM_STATUS_BYTECOUNT),
284 .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
285};
286
287static struct usb_ss_ep_comp_descriptor ss_ecm_intr_comp_desc = {
288 .bLength = sizeof ss_ecm_intr_comp_desc,
289 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
290
291 /* the following 3 values can be tweaked if necessary */
292 /* .bMaxBurst = 0, */
293 /* .bmAttributes = 0, */
294 .wBytesPerInterval = cpu_to_le16(ECM_STATUS_BYTECOUNT),
295};
296
297static struct usb_endpoint_descriptor ss_ecm_in_desc = {
298 .bLength = USB_DT_ENDPOINT_SIZE,
299 .bDescriptorType = USB_DT_ENDPOINT,
300
301 .bEndpointAddress = USB_DIR_IN,
302 .bmAttributes = USB_ENDPOINT_XFER_BULK,
303 .wMaxPacketSize = cpu_to_le16(1024),
304};
305
306static struct usb_endpoint_descriptor ss_ecm_out_desc = {
307 .bLength = USB_DT_ENDPOINT_SIZE,
308 .bDescriptorType = USB_DT_ENDPOINT,
309
310 .bEndpointAddress = USB_DIR_OUT,
311 .bmAttributes = USB_ENDPOINT_XFER_BULK,
312 .wMaxPacketSize = cpu_to_le16(1024),
313};
314
315static struct usb_ss_ep_comp_descriptor ss_ecm_bulk_comp_desc = {
316 .bLength = sizeof ss_ecm_bulk_comp_desc,
317 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
318
319 /* the following 2 values can be tweaked if necessary */
320 /* .bMaxBurst = 0, */
321 /* .bmAttributes = 0, */
322};
323
324static struct usb_descriptor_header *ecm_ss_function[] = {
325 /* CDC ECM control descriptors */
326 (struct usb_descriptor_header *) &ecm_control_intf,
327 (struct usb_descriptor_header *) &ecm_header_desc,
328 (struct usb_descriptor_header *) &ecm_union_desc,
329 (struct usb_descriptor_header *) &ecm_desc,
330
331 /* NOTE: status endpoint might need to be removed */
332 (struct usb_descriptor_header *) &ss_ecm_notify_desc,
333 (struct usb_descriptor_header *) &ss_ecm_intr_comp_desc,
334
335 /* data interface, altsettings 0 and 1 */
336 (struct usb_descriptor_header *) &ecm_data_nop_intf,
337 (struct usb_descriptor_header *) &ecm_data_intf,
338 (struct usb_descriptor_header *) &ss_ecm_in_desc,
339 (struct usb_descriptor_header *) &ss_ecm_bulk_comp_desc,
340 (struct usb_descriptor_header *) &ss_ecm_out_desc,
341 (struct usb_descriptor_header *) &ss_ecm_bulk_comp_desc,
342 NULL,
343};
344
268/* string descriptors: */ 345/* string descriptors: */
269 346
270static struct usb_string ecm_string_defs[] = { 347static struct usb_string ecm_string_defs[] = {
@@ -679,6 +756,20 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
679 goto fail; 756 goto fail;
680 } 757 }
681 758
759 if (gadget_is_superspeed(c->cdev->gadget)) {
760 ss_ecm_in_desc.bEndpointAddress =
761 fs_ecm_in_desc.bEndpointAddress;
762 ss_ecm_out_desc.bEndpointAddress =
763 fs_ecm_out_desc.bEndpointAddress;
764 ss_ecm_notify_desc.bEndpointAddress =
765 fs_ecm_notify_desc.bEndpointAddress;
766
767 /* copy descriptors, and track endpoint copies */
768 f->ss_descriptors = usb_copy_descriptors(ecm_ss_function);
769 if (!f->ss_descriptors)
770 goto fail;
771 }
772
682 /* NOTE: all that is done without knowing or caring about 773 /* NOTE: all that is done without knowing or caring about
683 * the network link ... which is unavailable to this code 774 * the network link ... which is unavailable to this code
684 * until we're activated via set_alt(). 775 * until we're activated via set_alt().
@@ -688,6 +779,7 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
688 ecm->port.close = ecm_close; 779 ecm->port.close = ecm_close;
689 780
690 DBG(cdev, "CDC Ethernet: %s speed IN/%s OUT/%s NOTIFY/%s\n", 781 DBG(cdev, "CDC Ethernet: %s speed IN/%s OUT/%s NOTIFY/%s\n",
782 gadget_is_superspeed(c->cdev->gadget) ? "super" :
691 gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", 783 gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
692 ecm->port.in_ep->name, ecm->port.out_ep->name, 784 ecm->port.in_ep->name, ecm->port.out_ep->name,
693 ecm->notify->name); 785 ecm->notify->name);
@@ -696,6 +788,8 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
696fail: 788fail:
697 if (f->descriptors) 789 if (f->descriptors)
698 usb_free_descriptors(f->descriptors); 790 usb_free_descriptors(f->descriptors);
791 if (f->hs_descriptors)
792 usb_free_descriptors(f->hs_descriptors);
699 793
700 if (ecm->notify_req) { 794 if (ecm->notify_req) {
701 kfree(ecm->notify_req->buf); 795 kfree(ecm->notify_req->buf);
@@ -722,6 +816,8 @@ ecm_unbind(struct usb_configuration *c, struct usb_function *f)
722 816
723 DBG(c->cdev, "ecm unbind\n"); 817 DBG(c->cdev, "ecm unbind\n");
724 818
819 if (gadget_is_superspeed(c->cdev->gadget))
820 usb_free_descriptors(f->ss_descriptors);
725 if (gadget_is_dualspeed(c->cdev->gadget)) 821 if (gadget_is_dualspeed(c->cdev->gadget))
726 usb_free_descriptors(f->hs_descriptors); 822 usb_free_descriptors(f->hs_descriptors);
727 usb_free_descriptors(f->descriptors); 823 usb_free_descriptors(f->descriptors);
diff --git a/drivers/usb/gadget/f_eem.c b/drivers/usb/gadget/f_eem.c
index 3e412740e2ef..046c6d0e6960 100644
--- a/drivers/usb/gadget/f_eem.c
+++ b/drivers/usb/gadget/f_eem.c
@@ -115,6 +115,45 @@ static struct usb_descriptor_header *eem_hs_function[] __initdata = {
115 NULL, 115 NULL,
116}; 116};
117 117
118/* super speed support: */
119
120static struct usb_endpoint_descriptor eem_ss_in_desc __initdata = {
121 .bLength = USB_DT_ENDPOINT_SIZE,
122 .bDescriptorType = USB_DT_ENDPOINT,
123
124 .bEndpointAddress = USB_DIR_IN,
125 .bmAttributes = USB_ENDPOINT_XFER_BULK,
126 .wMaxPacketSize = cpu_to_le16(1024),
127};
128
129static struct usb_endpoint_descriptor eem_ss_out_desc __initdata = {
130 .bLength = USB_DT_ENDPOINT_SIZE,
131 .bDescriptorType = USB_DT_ENDPOINT,
132
133 .bEndpointAddress = USB_DIR_OUT,
134 .bmAttributes = USB_ENDPOINT_XFER_BULK,
135 .wMaxPacketSize = cpu_to_le16(1024),
136};
137
138static struct usb_ss_ep_comp_descriptor eem_ss_bulk_comp_desc __initdata = {
139 .bLength = sizeof eem_ss_bulk_comp_desc,
140 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
141
142 /* the following 2 values can be tweaked if necessary */
143 /* .bMaxBurst = 0, */
144 /* .bmAttributes = 0, */
145};
146
147static struct usb_descriptor_header *eem_ss_function[] __initdata = {
148 /* CDC EEM control descriptors */
149 (struct usb_descriptor_header *) &eem_intf,
150 (struct usb_descriptor_header *) &eem_ss_in_desc,
151 (struct usb_descriptor_header *) &eem_ss_bulk_comp_desc,
152 (struct usb_descriptor_header *) &eem_ss_out_desc,
153 (struct usb_descriptor_header *) &eem_ss_bulk_comp_desc,
154 NULL,
155};
156
118/* string descriptors: */ 157/* string descriptors: */
119 158
120static struct usb_string eem_string_defs[] = { 159static struct usb_string eem_string_defs[] = {
@@ -265,7 +304,20 @@ eem_bind(struct usb_configuration *c, struct usb_function *f)
265 goto fail; 304 goto fail;
266 } 305 }
267 306
307 if (gadget_is_superspeed(c->cdev->gadget)) {
308 eem_ss_in_desc.bEndpointAddress =
309 eem_fs_in_desc.bEndpointAddress;
310 eem_ss_out_desc.bEndpointAddress =
311 eem_fs_out_desc.bEndpointAddress;
312
313 /* copy descriptors, and track endpoint copies */
314 f->ss_descriptors = usb_copy_descriptors(eem_ss_function);
315 if (!f->ss_descriptors)
316 goto fail;
317 }
318
268 DBG(cdev, "CDC Ethernet (EEM): %s speed IN/%s OUT/%s\n", 319 DBG(cdev, "CDC Ethernet (EEM): %s speed IN/%s OUT/%s\n",
320 gadget_is_superspeed(c->cdev->gadget) ? "super" :
269 gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", 321 gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
270 eem->port.in_ep->name, eem->port.out_ep->name); 322 eem->port.in_ep->name, eem->port.out_ep->name);
271 return 0; 323 return 0;
@@ -273,6 +325,8 @@ eem_bind(struct usb_configuration *c, struct usb_function *f)
273fail: 325fail:
274 if (f->descriptors) 326 if (f->descriptors)
275 usb_free_descriptors(f->descriptors); 327 usb_free_descriptors(f->descriptors);
328 if (f->hs_descriptors)
329 usb_free_descriptors(f->hs_descriptors);
276 330
277 /* we might as well release our claims on endpoints */ 331 /* we might as well release our claims on endpoints */
278 if (eem->port.out_ep->desc) 332 if (eem->port.out_ep->desc)
@@ -292,6 +346,8 @@ eem_unbind(struct usb_configuration *c, struct usb_function *f)
292 346
293 DBG(c->cdev, "eem unbind\n"); 347 DBG(c->cdev, "eem unbind\n");
294 348
349 if (gadget_is_superspeed(c->cdev->gadget))
350 usb_free_descriptors(f->ss_descriptors);
295 if (gadget_is_dualspeed(c->cdev->gadget)) 351 if (gadget_is_dualspeed(c->cdev->gadget))
296 usb_free_descriptors(f->hs_descriptors); 352 usb_free_descriptors(f->hs_descriptors);
297 usb_free_descriptors(f->descriptors); 353 usb_free_descriptors(f->descriptors);
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
index b324efa07733..8f3eae90919f 100644
--- a/drivers/usb/gadget/f_rndis.c
+++ b/drivers/usb/gadget/f_rndis.c
@@ -95,10 +95,12 @@ static inline struct f_rndis *func_to_rndis(struct usb_function *f)
95/* peak (theoretical) bulk transfer rate in bits-per-second */ 95/* peak (theoretical) bulk transfer rate in bits-per-second */
96static unsigned int bitrate(struct usb_gadget *g) 96static unsigned int bitrate(struct usb_gadget *g)
97{ 97{
98 if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) 98 if (gadget_is_superspeed(g) && g->speed == USB_SPEED_SUPER)
99 return 13 * 1024 * 8 * 1000 * 8;
100 else if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
99 return 13 * 512 * 8 * 1000 * 8; 101 return 13 * 512 * 8 * 1000 * 8;
100 else 102 else
101 return 19 * 64 * 1 * 1000 * 8; 103 return 19 * 64 * 1 * 1000 * 8;
102} 104}
103 105
104/*-------------------------------------------------------------------------*/ 106/*-------------------------------------------------------------------------*/
@@ -216,6 +218,7 @@ static struct usb_endpoint_descriptor fs_out_desc = {
216 218
217static struct usb_descriptor_header *eth_fs_function[] = { 219static struct usb_descriptor_header *eth_fs_function[] = {
218 (struct usb_descriptor_header *) &rndis_iad_descriptor, 220 (struct usb_descriptor_header *) &rndis_iad_descriptor,
221
219 /* control interface matches ACM, not Ethernet */ 222 /* control interface matches ACM, not Ethernet */
220 (struct usb_descriptor_header *) &rndis_control_intf, 223 (struct usb_descriptor_header *) &rndis_control_intf,
221 (struct usb_descriptor_header *) &header_desc, 224 (struct usb_descriptor_header *) &header_desc,
@@ -223,6 +226,7 @@ static struct usb_descriptor_header *eth_fs_function[] = {
223 (struct usb_descriptor_header *) &rndis_acm_descriptor, 226 (struct usb_descriptor_header *) &rndis_acm_descriptor,
224 (struct usb_descriptor_header *) &rndis_union_desc, 227 (struct usb_descriptor_header *) &rndis_union_desc,
225 (struct usb_descriptor_header *) &fs_notify_desc, 228 (struct usb_descriptor_header *) &fs_notify_desc,
229
226 /* data interface has no altsetting */ 230 /* data interface has no altsetting */
227 (struct usb_descriptor_header *) &rndis_data_intf, 231 (struct usb_descriptor_header *) &rndis_data_intf,
228 (struct usb_descriptor_header *) &fs_in_desc, 232 (struct usb_descriptor_header *) &fs_in_desc,
@@ -241,6 +245,7 @@ static struct usb_endpoint_descriptor hs_notify_desc = {
241 .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT), 245 .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT),
242 .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4, 246 .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
243}; 247};
248
244static struct usb_endpoint_descriptor hs_in_desc = { 249static struct usb_endpoint_descriptor hs_in_desc = {
245 .bLength = USB_DT_ENDPOINT_SIZE, 250 .bLength = USB_DT_ENDPOINT_SIZE,
246 .bDescriptorType = USB_DT_ENDPOINT, 251 .bDescriptorType = USB_DT_ENDPOINT,
@@ -261,6 +266,7 @@ static struct usb_endpoint_descriptor hs_out_desc = {
261 266
262static struct usb_descriptor_header *eth_hs_function[] = { 267static struct usb_descriptor_header *eth_hs_function[] = {
263 (struct usb_descriptor_header *) &rndis_iad_descriptor, 268 (struct usb_descriptor_header *) &rndis_iad_descriptor,
269
264 /* control interface matches ACM, not Ethernet */ 270 /* control interface matches ACM, not Ethernet */
265 (struct usb_descriptor_header *) &rndis_control_intf, 271 (struct usb_descriptor_header *) &rndis_control_intf,
266 (struct usb_descriptor_header *) &header_desc, 272 (struct usb_descriptor_header *) &header_desc,
@@ -268,6 +274,7 @@ static struct usb_descriptor_header *eth_hs_function[] = {
268 (struct usb_descriptor_header *) &rndis_acm_descriptor, 274 (struct usb_descriptor_header *) &rndis_acm_descriptor,
269 (struct usb_descriptor_header *) &rndis_union_desc, 275 (struct usb_descriptor_header *) &rndis_union_desc,
270 (struct usb_descriptor_header *) &hs_notify_desc, 276 (struct usb_descriptor_header *) &hs_notify_desc,
277
271 /* data interface has no altsetting */ 278 /* data interface has no altsetting */
272 (struct usb_descriptor_header *) &rndis_data_intf, 279 (struct usb_descriptor_header *) &rndis_data_intf,
273 (struct usb_descriptor_header *) &hs_in_desc, 280 (struct usb_descriptor_header *) &hs_in_desc,
@@ -275,6 +282,76 @@ static struct usb_descriptor_header *eth_hs_function[] = {
275 NULL, 282 NULL,
276}; 283};
277 284
285/* super speed support: */
286
287static struct usb_endpoint_descriptor ss_notify_desc = {
288 .bLength = USB_DT_ENDPOINT_SIZE,
289 .bDescriptorType = USB_DT_ENDPOINT,
290
291 .bEndpointAddress = USB_DIR_IN,
292 .bmAttributes = USB_ENDPOINT_XFER_INT,
293 .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT),
294 .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
295};
296
297static struct usb_ss_ep_comp_descriptor ss_intr_comp_desc = {
298 .bLength = sizeof ss_intr_comp_desc,
299 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
300
301 /* the following 3 values can be tweaked if necessary */
302 /* .bMaxBurst = 0, */
303 /* .bmAttributes = 0, */
304 .wBytesPerInterval = cpu_to_le16(STATUS_BYTECOUNT),
305};
306
307static struct usb_endpoint_descriptor ss_in_desc = {
308 .bLength = USB_DT_ENDPOINT_SIZE,
309 .bDescriptorType = USB_DT_ENDPOINT,
310
311 .bEndpointAddress = USB_DIR_IN,
312 .bmAttributes = USB_ENDPOINT_XFER_BULK,
313 .wMaxPacketSize = cpu_to_le16(1024),
314};
315
316static struct usb_endpoint_descriptor ss_out_desc = {
317 .bLength = USB_DT_ENDPOINT_SIZE,
318 .bDescriptorType = USB_DT_ENDPOINT,
319
320 .bEndpointAddress = USB_DIR_OUT,
321 .bmAttributes = USB_ENDPOINT_XFER_BULK,
322 .wMaxPacketSize = cpu_to_le16(1024),
323};
324
325static struct usb_ss_ep_comp_descriptor ss_bulk_comp_desc = {
326 .bLength = sizeof ss_bulk_comp_desc,
327 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
328
329 /* the following 2 values can be tweaked if necessary */
330 /* .bMaxBurst = 0, */
331 /* .bmAttributes = 0, */
332};
333
334static struct usb_descriptor_header *eth_ss_function[] = {
335 (struct usb_descriptor_header *) &rndis_iad_descriptor,
336
337 /* control interface matches ACM, not Ethernet */
338 (struct usb_descriptor_header *) &rndis_control_intf,
339 (struct usb_descriptor_header *) &header_desc,
340 (struct usb_descriptor_header *) &call_mgmt_descriptor,
341 (struct usb_descriptor_header *) &rndis_acm_descriptor,
342 (struct usb_descriptor_header *) &rndis_union_desc,
343 (struct usb_descriptor_header *) &ss_notify_desc,
344 (struct usb_descriptor_header *) &ss_intr_comp_desc,
345
346 /* data interface has no altsetting */
347 (struct usb_descriptor_header *) &rndis_data_intf,
348 (struct usb_descriptor_header *) &ss_in_desc,
349 (struct usb_descriptor_header *) &ss_bulk_comp_desc,
350 (struct usb_descriptor_header *) &ss_out_desc,
351 (struct usb_descriptor_header *) &ss_bulk_comp_desc,
352 NULL,
353};
354
278/* string descriptors: */ 355/* string descriptors: */
279 356
280static struct usb_string rndis_string_defs[] = { 357static struct usb_string rndis_string_defs[] = {
@@ -670,11 +747,24 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
670 747
671 /* copy descriptors, and track endpoint copies */ 748 /* copy descriptors, and track endpoint copies */
672 f->hs_descriptors = usb_copy_descriptors(eth_hs_function); 749 f->hs_descriptors = usb_copy_descriptors(eth_hs_function);
673
674 if (!f->hs_descriptors) 750 if (!f->hs_descriptors)
675 goto fail; 751 goto fail;
676 } 752 }
677 753
754 if (gadget_is_superspeed(c->cdev->gadget)) {
755 ss_in_desc.bEndpointAddress =
756 fs_in_desc.bEndpointAddress;
757 ss_out_desc.bEndpointAddress =
758 fs_out_desc.bEndpointAddress;
759 ss_notify_desc.bEndpointAddress =
760 fs_notify_desc.bEndpointAddress;
761
762 /* copy descriptors, and track endpoint copies */
763 f->ss_descriptors = usb_copy_descriptors(eth_ss_function);
764 if (!f->ss_descriptors)
765 goto fail;
766 }
767
678 rndis->port.open = rndis_open; 768 rndis->port.open = rndis_open;
679 rndis->port.close = rndis_close; 769 rndis->port.close = rndis_close;
680 770
@@ -699,12 +789,15 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f)
699 */ 789 */
700 790
701 DBG(cdev, "RNDIS: %s speed IN/%s OUT/%s NOTIFY/%s\n", 791 DBG(cdev, "RNDIS: %s speed IN/%s OUT/%s NOTIFY/%s\n",
792 gadget_is_superspeed(c->cdev->gadget) ? "super" :
702 gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", 793 gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
703 rndis->port.in_ep->name, rndis->port.out_ep->name, 794 rndis->port.in_ep->name, rndis->port.out_ep->name,
704 rndis->notify->name); 795 rndis->notify->name);
705 return 0; 796 return 0;
706 797
707fail: 798fail:
799 if (gadget_is_superspeed(c->cdev->gadget) && f->ss_descriptors)
800 usb_free_descriptors(f->ss_descriptors);
708 if (gadget_is_dualspeed(c->cdev->gadget) && f->hs_descriptors) 801 if (gadget_is_dualspeed(c->cdev->gadget) && f->hs_descriptors)
709 usb_free_descriptors(f->hs_descriptors); 802 usb_free_descriptors(f->hs_descriptors);
710 if (f->descriptors) 803 if (f->descriptors)
@@ -736,6 +829,8 @@ rndis_unbind(struct usb_configuration *c, struct usb_function *f)
736 rndis_deregister(rndis->config); 829 rndis_deregister(rndis->config);
737 rndis_exit(); 830 rndis_exit();
738 831
832 if (gadget_is_superspeed(c->cdev->gadget))
833 usb_free_descriptors(f->ss_descriptors);
739 if (gadget_is_dualspeed(c->cdev->gadget)) 834 if (gadget_is_dualspeed(c->cdev->gadget))
740 usb_free_descriptors(f->hs_descriptors); 835 usb_free_descriptors(f->hs_descriptors);
741 usb_free_descriptors(f->descriptors); 836 usb_free_descriptors(f->descriptors);
diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c
index 93bf676ef507..3dc53754ab60 100644
--- a/drivers/usb/gadget/f_subset.c
+++ b/drivers/usb/gadget/f_subset.c
@@ -201,6 +201,46 @@ static struct usb_descriptor_header *hs_eth_function[] __initdata = {
201 NULL, 201 NULL,
202}; 202};
203 203
204/* super speed support: */
205
206static struct usb_endpoint_descriptor ss_subset_in_desc __initdata = {
207 .bLength = USB_DT_ENDPOINT_SIZE,
208 .bDescriptorType = USB_DT_ENDPOINT,
209
210 .bmAttributes = USB_ENDPOINT_XFER_BULK,
211 .wMaxPacketSize = cpu_to_le16(1024),
212};
213
214static struct usb_endpoint_descriptor ss_subset_out_desc __initdata = {
215 .bLength = USB_DT_ENDPOINT_SIZE,
216 .bDescriptorType = USB_DT_ENDPOINT,
217
218 .bmAttributes = USB_ENDPOINT_XFER_BULK,
219 .wMaxPacketSize = cpu_to_le16(1024),
220};
221
222static struct usb_ss_ep_comp_descriptor ss_subset_bulk_comp_desc __initdata = {
223 .bLength = sizeof ss_subset_bulk_comp_desc,
224 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
225
226 /* the following 2 values can be tweaked if necessary */
227 /* .bMaxBurst = 0, */
228 /* .bmAttributes = 0, */
229};
230
231static struct usb_descriptor_header *ss_eth_function[] __initdata = {
232 (struct usb_descriptor_header *) &subset_data_intf,
233 (struct usb_descriptor_header *) &mdlm_header_desc,
234 (struct usb_descriptor_header *) &mdlm_desc,
235 (struct usb_descriptor_header *) &mdlm_detail_desc,
236 (struct usb_descriptor_header *) &ether_desc,
237 (struct usb_descriptor_header *) &ss_subset_in_desc,
238 (struct usb_descriptor_header *) &ss_subset_bulk_comp_desc,
239 (struct usb_descriptor_header *) &ss_subset_out_desc,
240 (struct usb_descriptor_header *) &ss_subset_bulk_comp_desc,
241 NULL,
242};
243
204/* string descriptors: */ 244/* string descriptors: */
205 245
206static struct usb_string geth_string_defs[] = { 246static struct usb_string geth_string_defs[] = {
@@ -290,6 +330,8 @@ geth_bind(struct usb_configuration *c, struct usb_function *f)
290 330
291 /* copy descriptors, and track endpoint copies */ 331 /* copy descriptors, and track endpoint copies */
292 f->descriptors = usb_copy_descriptors(fs_eth_function); 332 f->descriptors = usb_copy_descriptors(fs_eth_function);
333 if (!f->descriptors)
334 goto fail;
293 335
294 /* support all relevant hardware speeds... we expect that when 336 /* support all relevant hardware speeds... we expect that when
295 * hardware is dual speed, all bulk-capable endpoints work at 337 * hardware is dual speed, all bulk-capable endpoints work at
@@ -303,6 +345,20 @@ geth_bind(struct usb_configuration *c, struct usb_function *f)
303 345
304 /* copy descriptors, and track endpoint copies */ 346 /* copy descriptors, and track endpoint copies */
305 f->hs_descriptors = usb_copy_descriptors(hs_eth_function); 347 f->hs_descriptors = usb_copy_descriptors(hs_eth_function);
348 if (!f->hs_descriptors)
349 goto fail;
350 }
351
352 if (gadget_is_superspeed(c->cdev->gadget)) {
353 ss_subset_in_desc.bEndpointAddress =
354 fs_subset_in_desc.bEndpointAddress;
355 ss_subset_out_desc.bEndpointAddress =
356 fs_subset_out_desc.bEndpointAddress;
357
358 /* copy descriptors, and track endpoint copies */
359 f->ss_descriptors = usb_copy_descriptors(ss_eth_function);
360 if (!f->ss_descriptors)
361 goto fail;
306 } 362 }
307 363
308 /* NOTE: all that is done without knowing or caring about 364 /* NOTE: all that is done without knowing or caring about
@@ -311,11 +367,17 @@ geth_bind(struct usb_configuration *c, struct usb_function *f)
311 */ 367 */
312 368
313 DBG(cdev, "CDC Subset: %s speed IN/%s OUT/%s\n", 369 DBG(cdev, "CDC Subset: %s speed IN/%s OUT/%s\n",
370 gadget_is_superspeed(c->cdev->gadget) ? "super" :
314 gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", 371 gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
315 geth->port.in_ep->name, geth->port.out_ep->name); 372 geth->port.in_ep->name, geth->port.out_ep->name);
316 return 0; 373 return 0;
317 374
318fail: 375fail:
376 if (f->descriptors)
377 usb_free_descriptors(f->descriptors);
378 if (f->hs_descriptors)
379 usb_free_descriptors(f->hs_descriptors);
380
319 /* we might as well release our claims on endpoints */ 381 /* we might as well release our claims on endpoints */
320 if (geth->port.out_ep->desc) 382 if (geth->port.out_ep->desc)
321 geth->port.out_ep->driver_data = NULL; 383 geth->port.out_ep->driver_data = NULL;
@@ -330,6 +392,8 @@ fail:
330static void 392static void
331geth_unbind(struct usb_configuration *c, struct usb_function *f) 393geth_unbind(struct usb_configuration *c, struct usb_function *f)
332{ 394{
395 if (gadget_is_superspeed(c->cdev->gadget))
396 usb_free_descriptors(f->ss_descriptors);
333 if (gadget_is_dualspeed(c->cdev->gadget)) 397 if (gadget_is_dualspeed(c->cdev->gadget))
334 usb_free_descriptors(f->hs_descriptors); 398 usb_free_descriptors(f->hs_descriptors);
335 usb_free_descriptors(f->descriptors); 399 usb_free_descriptors(f->descriptors);
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
index b91363e88db7..dfed4c1d96c0 100644
--- a/drivers/usb/gadget/u_ether.c
+++ b/drivers/usb/gadget/u_ether.c
@@ -97,16 +97,17 @@ struct eth_dev {
97 97
98static unsigned qmult = 5; 98static unsigned qmult = 5;
99module_param(qmult, uint, S_IRUGO|S_IWUSR); 99module_param(qmult, uint, S_IRUGO|S_IWUSR);
100MODULE_PARM_DESC(qmult, "queue length multiplier at high speed"); 100MODULE_PARM_DESC(qmult, "queue length multiplier at high/super speed");
101 101
102#else /* full speed (low speed doesn't do bulk) */ 102#else /* full speed (low speed doesn't do bulk) */
103#define qmult 1 103#define qmult 1
104#endif 104#endif
105 105
106/* for dual-speed hardware, use deeper queues at highspeed */ 106/* for dual-speed hardware, use deeper queues at high/super speed */
107static inline int qlen(struct usb_gadget *gadget) 107static inline int qlen(struct usb_gadget *gadget)
108{ 108{
109 if (gadget_is_dualspeed(gadget) && gadget->speed == USB_SPEED_HIGH) 109 if (gadget_is_dualspeed(gadget) && (gadget->speed == USB_SPEED_HIGH ||
110 gadget->speed == USB_SPEED_SUPER))
110 return qmult * DEFAULT_QLEN; 111 return qmult * DEFAULT_QLEN;
111 else 112 else
112 return DEFAULT_QLEN; 113 return DEFAULT_QLEN;
@@ -598,9 +599,10 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb,
598 599
599 req->length = length; 600 req->length = length;
600 601
601 /* throttle highspeed IRQ rate back slightly */ 602 /* throttle high/super speed IRQ rate back slightly */
602 if (gadget_is_dualspeed(dev->gadget)) 603 if (gadget_is_dualspeed(dev->gadget))
603 req->no_interrupt = (dev->gadget->speed == USB_SPEED_HIGH) 604 req->no_interrupt = (dev->gadget->speed == USB_SPEED_HIGH ||
605 dev->gadget->speed == USB_SPEED_SUPER)
604 ? ((atomic_read(&dev->tx_qlen) % qmult) != 0) 606 ? ((atomic_read(&dev->tx_qlen) % qmult) != 0)
605 : 0; 607 : 0;
606 608