Skip to content

Commit 04617db

Browse files
Paul ZimmermanFelipe Balbi
authored andcommitted
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 <[email protected]> Signed-off-by: Felipe Balbi <[email protected]>
1 parent 96fe53e commit 04617db

File tree

6 files changed

+324
-11
lines changed

6 files changed

+324
-11
lines changed

drivers/usb/gadget/ether.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ static struct usb_composite_driver eth_driver = {
401401
.name = "g_ether",
402402
.dev = &device_desc,
403403
.strings = dev_strings,
404-
.max_speed = USB_SPEED_HIGH,
404+
.max_speed = USB_SPEED_SUPER,
405405
.unbind = __exit_p(eth_unbind),
406406
};
407407

drivers/usb/gadget/f_ecm.c

Lines changed: 98 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,12 @@ static inline struct f_ecm *func_to_ecm(struct usb_function *f)
7777
/* peak (theoretical) bulk transfer rate in bits-per-second */
7878
static inline unsigned ecm_bitrate(struct usb_gadget *g)
7979
{
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)
8183
return 13 * 512 * 8 * 1000 * 8;
8284
else
83-
return 19 * 64 * 1 * 1000 * 8;
85+
return 19 * 64 * 1 * 1000 * 8;
8486
}
8587

8688
/*-------------------------------------------------------------------------*/
@@ -210,8 +212,10 @@ static struct usb_descriptor_header *ecm_fs_function[] = {
210212
(struct usb_descriptor_header *) &ecm_header_desc,
211213
(struct usb_descriptor_header *) &ecm_union_desc,
212214
(struct usb_descriptor_header *) &ecm_desc,
215+
213216
/* NOTE: status endpoint might need to be removed */
214217
(struct usb_descriptor_header *) &fs_ecm_notify_desc,
218+
215219
/* data interface, altsettings 0 and 1 */
216220
(struct usb_descriptor_header *) &ecm_data_nop_intf,
217221
(struct usb_descriptor_header *) &ecm_data_intf,
@@ -231,6 +235,7 @@ static struct usb_endpoint_descriptor hs_ecm_notify_desc = {
231235
.wMaxPacketSize = cpu_to_le16(ECM_STATUS_BYTECOUNT),
232236
.bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
233237
};
238+
234239
static struct usb_endpoint_descriptor hs_ecm_in_desc = {
235240
.bLength = USB_DT_ENDPOINT_SIZE,
236241
.bDescriptorType = USB_DT_ENDPOINT,
@@ -255,8 +260,10 @@ static struct usb_descriptor_header *ecm_hs_function[] = {
255260
(struct usb_descriptor_header *) &ecm_header_desc,
256261
(struct usb_descriptor_header *) &ecm_union_desc,
257262
(struct usb_descriptor_header *) &ecm_desc,
263+
258264
/* NOTE: status endpoint might need to be removed */
259265
(struct usb_descriptor_header *) &hs_ecm_notify_desc,
266+
260267
/* data interface, altsettings 0 and 1 */
261268
(struct usb_descriptor_header *) &ecm_data_nop_intf,
262269
(struct usb_descriptor_header *) &ecm_data_intf,
@@ -265,6 +272,76 @@ static struct usb_descriptor_header *ecm_hs_function[] = {
265272
NULL,
266273
};
267274

275+
/* super speed support: */
276+
277+
static 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+
287+
static 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+
297+
static 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+
306+
static 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+
315+
static 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+
324+
static 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+
268345
/* string descriptors: */
269346

270347
static struct usb_string ecm_string_defs[] = {
@@ -679,6 +756,20 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
679756
goto fail;
680757
}
681758

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+
682773
/* NOTE: all that is done without knowing or caring about
683774
* the network link ... which is unavailable to this code
684775
* until we're activated via set_alt().
@@ -688,6 +779,7 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
688779
ecm->port.close = ecm_close;
689780

690781
DBG(cdev, "CDC Ethernet: %s speed IN/%s OUT/%s NOTIFY/%s\n",
782+
gadget_is_superspeed(c->cdev->gadget) ? "super" :
691783
gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
692784
ecm->port.in_ep->name, ecm->port.out_ep->name,
693785
ecm->notify->name);
@@ -696,6 +788,8 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
696788
fail:
697789
if (f->descriptors)
698790
usb_free_descriptors(f->descriptors);
791+
if (f->hs_descriptors)
792+
usb_free_descriptors(f->hs_descriptors);
699793

700794
if (ecm->notify_req) {
701795
kfree(ecm->notify_req->buf);
@@ -722,6 +816,8 @@ ecm_unbind(struct usb_configuration *c, struct usb_function *f)
722816

723817
DBG(c->cdev, "ecm unbind\n");
724818

819+
if (gadget_is_superspeed(c->cdev->gadget))
820+
usb_free_descriptors(f->ss_descriptors);
725821
if (gadget_is_dualspeed(c->cdev->gadget))
726822
usb_free_descriptors(f->hs_descriptors);
727823
usb_free_descriptors(f->descriptors);

drivers/usb/gadget/f_eem.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,45 @@ static struct usb_descriptor_header *eem_hs_function[] __initdata = {
115115
NULL,
116116
};
117117

118+
/* super speed support: */
119+
120+
static 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+
129+
static 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+
138+
static 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+
147+
static 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+
118157
/* string descriptors: */
119158

120159
static struct usb_string eem_string_defs[] = {
@@ -265,14 +304,29 @@ eem_bind(struct usb_configuration *c, struct usb_function *f)
265304
goto fail;
266305
}
267306

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+
268319
DBG(cdev, "CDC Ethernet (EEM): %s speed IN/%s OUT/%s\n",
320+
gadget_is_superspeed(c->cdev->gadget) ? "super" :
269321
gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
270322
eem->port.in_ep->name, eem->port.out_ep->name);
271323
return 0;
272324

273325
fail:
274326
if (f->descriptors)
275327
usb_free_descriptors(f->descriptors);
328+
if (f->hs_descriptors)
329+
usb_free_descriptors(f->hs_descriptors);
276330

277331
/* we might as well release our claims on endpoints */
278332
if (eem->port.out_ep->desc)
@@ -292,6 +346,8 @@ eem_unbind(struct usb_configuration *c, struct usb_function *f)
292346

293347
DBG(c->cdev, "eem unbind\n");
294348

349+
if (gadget_is_superspeed(c->cdev->gadget))
350+
usb_free_descriptors(f->ss_descriptors);
295351
if (gadget_is_dualspeed(c->cdev->gadget))
296352
usb_free_descriptors(f->hs_descriptors);
297353
usb_free_descriptors(f->descriptors);

0 commit comments

Comments
 (0)