QcomModulePkg: Add support for super speed

Add support for descriptors required for usb enemurations in super speed
mode.

Change-Id: I08a14e7cd5b3967c9fdabd26944b245d388da990
diff --git a/QcomModulePkg/Application/FastbootApp/FastbootMain.c b/QcomModulePkg/Application/FastbootApp/FastbootMain.c
index b51b0fd..ee42547 100644
--- a/QcomModulePkg/Application/FastbootApp/FastbootMain.c
+++ b/QcomModulePkg/Application/FastbootApp/FastbootMain.c
@@ -58,6 +58,41 @@
 
 /* Global fastboot data */
 static FastbootDeviceData Fbd;
+static USB_DEVICE_DESCRIPTOR_SET DescSet;
+
+STATIC
+CONST
+struct {
+  EFI_USB_BOS_DESCRIPTOR                BosDescriptor;
+  EFI_USB_USB_20_EXTENSION_DESCRIPTOR   Usb2ExtDescriptor;
+  EFI_USB_SUPERSPEED_USB_DESCRIPTOR     SsUsbDescriptor;
+} BinaryObjectStore = {
+  // BOS Descriptor
+  {
+    sizeof(EFI_USB_BOS_DESCRIPTOR),               // Descriptor Size
+    USB_DESC_TYPE_BOS,                            // Descriptor Type
+    sizeof(BinaryObjectStore),                    // Total Length
+    2                                             // Number of device capabilities
+  },
+  // USB2 Extension Desc
+  {
+    sizeof(EFI_USB_USB_20_EXTENSION_DESCRIPTOR),  // Descriptor Size
+    USB_DESC_TYPE_DEVICE_CAPABILITY,              // Device Capability Type descriptor
+    USB_DEV_CAP_TYPE_USB_20_EXTENSION,            // USB 2.0 Extension Capability Type
+    0x6                                           // Supported device level features
+  },
+  // Super Speed Device Capability Desc
+  {
+    sizeof(EFI_USB_SUPERSPEED_USB_DESCRIPTOR),    // Descriptor Size
+    USB_DESC_TYPE_DEVICE_CAPABILITY,              // Device Capability Type descriptor
+    USB_DEV_CAP_TYPE_SUPERSPEED_USB,              // SuperSpeed Device Capability Type
+    0x00,                                         // Supported device level features
+    0x0E,                                         // Speeds Supported by the device: SS, HS and FS
+    0x01,                                         // Functionality support
+    0x07,                                         // U1 Device Exit Latency
+    0x65                                          // U2 Device Exit Latency
+  }
+};
 
 FastbootDeviceData GetFastbootDeviceData()
 {
@@ -74,7 +109,9 @@
 {
   EFI_STATUS                    Status;
   USB_DEVICE_DESCRIPTOR         *DevDesc;
+  USB_DEVICE_DESCRIPTOR         *SSDevDesc;
   VOID                          *Descriptors;
+  VOID                          *SSDescriptors;
   EFI_EVENT                     UsbConfigEvt;
   EFI_GUID                      UsbDeviceProtolGuid =
                                 { 0xd9d9ce48, 0x44b8, 0x4f49,
@@ -106,10 +143,19 @@
   }
 
   /* Build the descriptor for fastboot */
-  BuildDefaultDescriptors(&DevDesc, &Descriptors);
-  
+  BuildDefaultDescriptors(&DevDesc, &Descriptors, &SSDevDesc, &SSDescriptors);
+
+  DescSet.DeviceDescriptor = DevDesc;
+  DescSet.Descriptors = &Descriptors;
+  DescSet.SSDeviceDescriptor = SSDevDesc;
+  DescSet.SSDescriptors = &SSDescriptors;
+  DescSet.DeviceQualifierDescriptor = &DeviceQualifier;
+  DescSet.BinaryDeviceOjectStore =  (VOID *) &BinaryObjectStore;
+  DescSet.StringDescriptorCount = 5;
+  DescSet.StringDescritors = StrDescriptors;
+
   /* Start the usb device */
-  Status = Fbd.UsbDeviceProtocol->Start(DevDesc, &Descriptors, &DeviceQualifier, NULL, 5, StrDescriptors);
+  Status = Fbd.UsbDeviceProtocol->StartEx(&DescSet);
 
   /* Allocate buffers required to receive the data from Host*/
   Status = Fbd.UsbDeviceProtocol->AllocateTransferBuffer(USB_BUFF_SIZE, &Fbd.gRxBuffer);
diff --git a/QcomModulePkg/Application/FastbootApp/UsbDescriptors.c b/QcomModulePkg/Application/FastbootApp/UsbDescriptors.c
index 3272633..1042221 100644
--- a/QcomModulePkg/Application/FastbootApp/UsbDescriptors.c
+++ b/QcomModulePkg/Application/FastbootApp/UsbDescriptors.c
@@ -40,7 +40,7 @@
 DeviceDescriptor = {
   sizeof(EFI_USB_DEVICE_DESCRIPTOR),  // uint8  bLength;
   USB_DESC_TYPE_DEVICE,               // uint8  bDescriptorType;
-  0x0200,                             // uint16 bcdUSB;
+  0x0210,                             // uint16 bcdUSB;
   0x00,                               // uint8  bDeviceClass;
   0x00,                               // uint8  bDeviceSubClass;
   0x00,                               // uint8  bDeviceProtocol;
@@ -54,6 +54,24 @@
   1                                   // uint8  bNumConfigurations;
 };
 
+STATIC
+EFI_USB_DEVICE_DESCRIPTOR
+SSDeviceDescriptor = {
+  sizeof(EFI_USB_DEVICE_DESCRIPTOR),  // uint8  bLength;
+  USB_DESC_TYPE_DEVICE,               // uint8  bDescriptorType;
+  0x0300,                             // uint16 bcdUSB;
+  0x00,                               // uint8  bDeviceClass;
+  0x00,                               // uint8  bDeviceSubClass;
+  0x00,                               // uint8  bDeviceProtocol;
+  9,                                  // uint8  bMaxPacketSize0;
+  FAST_BOOT_VENDOR,                   // uint16 idVendor;
+  FAST_BOOT_IDPRODUCT,                // uint16 idProduct;
+  0x100,                              // uint16 bcdDevice;
+  1,                                  // uint8  iManufacturer;
+  2,                                  // uint8  iProduct;
+  3,                                  // uint8  iSerialNumber;
+  1                                   // uint8  bNumConfigurations;
+};
 
 EFI_USB_DEVICE_QUALIFIER_DESCRIPTOR
 DeviceQualifier = {
@@ -68,6 +86,68 @@
   0                                             // uint8  bReserved;
 };
 
+STATIC
+struct _SSCfgDescTree {
+  EFI_USB_CONFIG_DESCRIPTOR    ConfigDescriptor;
+  EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
+  EFI_USB_ENDPOINT_DESCRIPTOR  EndpointDescriptor0;
+  EFI_USB_SS_ENDPOINT_COMPANION_DESCRIPTOR EndpointCompanionDescriptor0;
+  EFI_USB_ENDPOINT_DESCRIPTOR  EndpointDescriptor1;
+  EFI_USB_SS_ENDPOINT_COMPANION_DESCRIPTOR EndpointCompanionDescriptor1;
+} TotalSSConfigDescriptor = {
+  {
+    sizeof(EFI_USB_CONFIG_DESCRIPTOR),      // uint8  bLength;
+    USB_DESC_TYPE_CONFIG,                   // uint8  bDescriptorType;
+    sizeof(TotalSSConfigDescriptor),        // uint16 wTotalLength;
+    1,                                      // uint8  bNumInterfaces;
+    1,                                      // uint8  bConfigurationValue;
+    0,                                      // uint8  iConfiguration;
+    0x80,                                   // uint8  bmAttributes;
+    0x10                                    // uint8  bMaxPower;
+  },
+  {
+    sizeof(EFI_USB_INTERFACE_DESCRIPTOR), // uint8  bLength;
+    USB_DESC_TYPE_INTERFACE,              // uint8  bDescriptorType;
+    0,                                    // uint8  bInterfaceNumber;
+    0,                                    // uint8  bAlternateSetting;
+    2,                                    // uint8  bNumEndpoints;
+    0xff,                                 // uint8  bInterfaceClass;
+    0x42,                                 // uint8  bInterfaceSubClass;
+    0x03,                                 // uint8  bInterfaceProtocol;
+    4
+  },
+  {
+    sizeof(EFI_USB_ENDPOINT_DESCRIPTOR), // uint8  bLength;
+    USB_DESC_TYPE_ENDPOINT,              // uint8  bDescriptorType;
+    ENDPOINT_ADDR(USBLB_BULK_EP, TRUE),  // uint8  bEndpointAddress;
+    USB_ENDPOINT_BULK,                   // uint8  bmAttributes;
+    1024,                                // uint16 wMaxPacketSize; SS=1024, HS=512 , FS=64
+    0                                    // uint8  bInterval;
+  },
+  {
+    sizeof(EFI_USB_SS_ENDPOINT_COMPANION_DESCRIPTOR), // uint8 bLength
+    USB_DESC_TYPE_SS_ENDPOINT_COMPANION,                      // uint8 bDescriptorType
+    4,                                                        // uint8 bMaxBurst,    0 => max burst 1
+    0,                                                        // uint8 bmAttributes, 0 => no stream
+    0,                                                        // uint8 wBytesPerInterval. Does not apply to BULK
+  },
+  {
+    sizeof(EFI_USB_ENDPOINT_DESCRIPTOR), // uint8  bLength;
+    USB_DESC_TYPE_ENDPOINT,              // uint8  bDescriptorType;
+    ENDPOINT_ADDR(USBLB_BULK_EP, FALSE), // uint8  bEndpointAddress;
+    USB_ENDPOINT_BULK,                   // uint8  bmAttributes;
+    1024,                                // uint16 wMaxPacketSize; SS=1024, HS=512 , FS=64
+    0                                    // uint8  bInterval;
+  },
+  {
+    sizeof(EFI_USB_SS_ENDPOINT_COMPANION_DESCRIPTOR), // uint8 bLength
+    USB_DESC_TYPE_SS_ENDPOINT_COMPANION,                      // uint8 bDescriptorType
+    4,                                                        // uint8 bMaxBurst,    0 => max burst 1
+    0,                                                        // uint8 bmAttributes, 0 => no stream
+    0,                                                        // uint8 wBytesPerInterval. Does not apply to BULK
+  }
+};
+
 #pragma pack(1)
 typedef struct _CfgDescTree {
   EFI_USB_CONFIG_DESCRIPTOR    ConfigDescriptor;
@@ -182,10 +262,13 @@
 VOID
 BuildDefaultDescriptors(
   OUT USB_DEVICE_DESCRIPTOR  **DevDesc,
-  OUT VOID                  **Descriptors)
+  OUT VOID                  **Descriptors,
+  OUT USB_DEVICE_DESCRIPTOR  **SSDevDesc,
+  OUT VOID                  **SSDescriptors)
 {
   UINT8                        Index = 0;
   UINT8                        NumCfg = 0; 
+  UINT8                        NumCfgSS = 0;
   CHAR8                        Str_UUID[64];
   UINT32                       i;
   EFI_STATUS                   Status;
@@ -205,17 +288,29 @@
   }
 
   *DevDesc = &DeviceDescriptor;
+  *SSDevDesc = &SSDeviceDescriptor;
   NumCfg   = DeviceDescriptor.NumConfigurations;
+  NumCfgSS   = SSDeviceDescriptor.NumConfigurations;
 
   *Descriptors = AllocatePool(NumCfg * sizeof (struct _CfgDescTree *));
   if (Descriptors == NULL)
   {
-    DEBUG ((EFI_D_ERROR, "Error Allocating memory for config descriptors\n"));
+    DEBUG ((EFI_D_ERROR, "Error Allocating memory for HS config descriptors\n"));
     return;
   }
 
+  *SSDescriptors = AllocatePool(NumCfg * sizeof (struct _SSCfgDescTree *));
+  if (SSDescriptors == NULL)
+  {
+    DEBUG ((EFI_D_ERROR, "Error Allocating memory for SS config descriptors\n"));
+    return;
+  }
   for (Index = 0; Index < NumCfg; Index++)
   {
     Descriptors[Index] = &TotalConfigDescriptor;
   }
+  for (Index = 0; Index < NumCfg; Index++)
+  {
+    SSDescriptors[Index] = &TotalSSConfigDescriptor;
+  }
 }
diff --git a/QcomModulePkg/Application/FastbootApp/UsbDescriptors.h b/QcomModulePkg/Application/FastbootApp/UsbDescriptors.h
index 45e9887..59fb605 100644
--- a/QcomModulePkg/Application/FastbootApp/UsbDescriptors.h
+++ b/QcomModulePkg/Application/FastbootApp/UsbDescriptors.h
@@ -51,5 +51,6 @@
 extern EFI_USB_STRING_DESCRIPTOR *StrDescriptors[5];
 
 VOID
-BuildDefaultDescriptors(OUT USB_DEVICE_DESCRIPTOR **DevDesc, OUT VOID **Descriptors);
+BuildDefaultDescriptors(OUT USB_DEVICE_DESCRIPTOR **DevDesc, OUT VOID **Descriptors,
+			            OUT USB_DEVICE_DESCRIPTOR **SSDevDesc, OUT VOID **SSDescriptors);
 #endif /* _USBFN_DESCAPP_H_ */