@@ -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 */
7878static 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+
234239static 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
270347static 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)
696788fail :
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 );
0 commit comments