ASR_BASE
Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/marvell/obm/Common/Download/ASR_USB/usb2_enumeration.c b/marvell/obm/Common/Download/ASR_USB/usb2_enumeration.c
new file mode 100644
index 0000000..106e91a
--- /dev/null
+++ b/marvell/obm/Common/Download/ASR_USB/usb2_enumeration.c
@@ -0,0 +1,269 @@
+/******************************************************************************
+ *
+ * (C)Copyright 2013 Marvell. All Rights Reserved.
+ *
+ * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MARVELL.
+ * The copyright notice above does not evidence any actual or intended
+ * publication of such source code.
+ * This Module contains Proprietary Information of Marvell and should be
+ * treated as Confidential.
+ * The information in this file is provided for the exclusive use of the
+ * licensees of Marvell.
+ * Such users have the right to use, modify, and incorporate this code into
+ * products for purposes authorized by the license agreement provided they
+ * include this notice and the associated copyright notice with any such
+ * product.
+ * The information in this file is provided "AS IS" without warranty.
+ *
+ ******************************************************************************/
+
+
+#include "Typedef.h"
+#include "misc.h"
+#include "usb_descriptors.h"
+#include "usbdefs.h"
+#include "usb2_main.h"
+#include "usb2_enumeration.h"
+#include "usbapi.h"
+
+#if BOOTROM
+#include "Bootrom.h"
+#endif
+
+//these are allocated in UsbDescriptors.c
+extern OPT_USB_DESCRIPTOR_LOADS USBDescriptors[NUM_USB_DESCRIPTORS];
+extern CHAR USB2DevQualDesc[];
+extern CHAR USB1ConfigDesc[];
+extern UINT_T USBStringIndexTable[MAX_USB_STRINGS];
+extern void USB2D_VendorRequest(P_DC_Properties_T pDCProps, P_XLLP_USB_SETUP_DATA_T pSetupPacket);
+
+void USB2D_EnumerationHandler(P_DC_Properties_T pDCProps, P_XLLP_USB_SETUP_DATA_T pSetupPacket)
+{
+ switch (pSetupPacket->bmRequestType & 0x60)
+ {
+ case STANDARD_REQ:
+ switch (pSetupPacket->bRequest)
+ {
+ case REQ_GET_STATUS:
+ USB2D_GetStatus(pDCProps, pSetupPacket);
+ break;
+// case REQ_CLEAR_FEATURE:
+// mvUsbCh9ClearFeature(handle, setup, &ci_otg_setupPacket);
+// break;
+// case REQ_SET_FEATURE:
+// mvUsbCh9SetFeature(handle, setup, &ci_otg_setupPacket);
+// break;
+ case REQ_SET_ADDRESS:
+ USB2D_SetAddress(pDCProps, pSetupPacket);
+ break;
+ case REQ_GET_DESCRIPTOR:
+ USB2D_GetDescriptor(pDCProps, pSetupPacket);
+ break;
+// case REQ_SET_DESCRIPTOR:
+// mvUsbCh9SetDescriptior(handle, setup, &ci_otg_setupPacket);
+// break;
+// case REQ_GET_CONFIGURATION:
+// mvUsbCh9GetConfig(handle, setup, &ci_otg_setupPacket);
+// break;
+ case REQ_SET_CONFIGURATION:
+ USB2D_SetConfig(pDCProps, pSetupPacket);
+ break;
+// case REQ_GET_INTERFACE:
+// mvUsbCh9GetInterface(handle, setup, &ci_otg_setupPacket);
+// break;
+// case REQ_SET_INTERFACE:
+// mvUsbCh9SetInterface(handle, setup, &ci_otg_setupPacket);
+// break;
+ default:
+ //unhandled descriptor. send a STALL PID
+ pDCProps->pUSBRegs->ENDPTCTRLX[USB_ENDPOINT_0] |= BIT0; //set the RX EP0 STALL bit (RXS)
+ break;
+ } // Endswitch
+ break;
+ case VENDOR_REQ:
+ USB2D_VendorRequest(pDCProps, pSetupPacket);
+ break;
+ default:
+ //unhandled descriptor. send a STALL PID
+ pDCProps->pUSBRegs->ENDPTCTRLX[USB_ENDPOINT_0] |= BIT0; //set the RX EP0 STALL bit (RXS)
+ break;
+ } //Endswitch
+}
+
+void USB2D_GetDescriptor(P_DC_Properties_T pDCProps, P_XLLP_USB_SETUP_DATA_T pSetupPacket)
+{
+ UINT pktSize, stringLength, stringIndex;
+ UCHAR *payload = "UNHANDLED";
+
+ // Load the appropriate string depending on the descriptor requested
+ switch (pSetupPacket->wValue >> 8)
+ {
+ case DESC_TYPE_DEVICE:
+ pktSize = USBDescriptors[USB_DEVICE_DESCRIPTOR & 0xFF].DesSize;
+ payload = (UCHAR*)(USBDescriptors[USB_DEVICE_DESCRIPTOR & 0xFF].pDesPayload);
+ break;
+ case DESC_TYPE_CONFIG:
+ pktSize = USBDescriptors[USB_CONFIG_DESCRIPTOR & 0xFF].DesSize;
+ payload = (UCHAR*)(USBDescriptors[USB_CONFIG_DESCRIPTOR & 0xFF].pDesPayload);
+ break;
+ case DESC_TYPE_STRING:
+ stringIndex = ((pSetupPacket->wValue) & 0xFF);
+ // Bounds protection
+ if (stringIndex >= MAX_USB_STRINGS)
+ {
+ stringLength = (pSetupPacket->wLength);
+ if (stringLength > USBDescriptors[USB_DEFAULT_STRING_DESCRIPTOR & 0xFF].DesSize)
+ pktSize = USBDescriptors[USB_DEFAULT_STRING_DESCRIPTOR & 0xFF].DesSize;
+ else
+ pktSize = stringLength;
+ payload =(UCHAR*)(USBDescriptors[USB_DEFAULT_STRING_DESCRIPTOR & 0xFF].pDesPayload);
+ break;
+ }
+ switch (USBStringIndexTable[stringIndex])
+ {
+ case USB_LANGUAGE_STRING_DESCRIPTOR:
+ case USB_MANUFACTURER_STRING_DESCRIPTOR:
+ case USB_PRODUCT_STRING_DESCRIPTOR:
+ case USB_SERIAL_STRING_DESCRIPTOR:
+ case USB_INTERFACE_STRING_DESCRIPTOR:
+ case USB_DEFAULT_STRING_DESCRIPTOR:
+ stringLength = (pSetupPacket->wLength);
+ if (stringLength > USBDescriptors[USBStringIndexTable[stringIndex] & 0xFF].DesSize)
+ pktSize = USBDescriptors[USBStringIndexTable[stringIndex] & 0xFF].DesSize;
+ else
+ pktSize = stringLength;
+ payload = (UCHAR*)(USBDescriptors[USBStringIndexTable[stringIndex] & 0xFF].pDesPayload);
+ break;
+ default:
+ //unhandled descriptor. set length to 0
+ pktSize = 0;
+ break;
+ }
+ break; // from DESC_TYPE_STRING
+ case DESC_TYPE_INTERFACE:
+ pktSize = USBDescriptors[USB_INTERFACE_DESCRIPTOR & 0xFF].DesSize;
+ payload = (UCHAR*)(USBDescriptors[USB_INTERFACE_DESCRIPTOR & 0xFF].pDesPayload);
+ break;
+ case DESC_TYPE_ENDPOINT:
+ pktSize = USBDescriptors[USB_ENDPOINT_DESCRIPTOR & 0xFF].DesSize;
+ payload = (UCHAR*)(USBDescriptors[USB_ENDPOINT_DESCRIPTOR & 0xFF].pDesPayload);
+ break;
+ case DESC_TYPE_QUALIFIER:
+ //getting this request means the host wants us to run at FULL speed...
+ pktSize = USB2DevQualDesc[0]; //bLength field
+ payload = (UCHAR*) USB2DevQualDesc;
+ //overwrite the CONFIG descriptor to point to the FULL speed version
+ USBDescriptors[USB_CONFIG_DESCRIPTOR & 0xFF].DesSize = (USB1ConfigDesc[2]) + (USB1ConfigDesc[3] << 8); //LSB + MSB
+ USBDescriptors[USB_CONFIG_DESCRIPTOR & 0xFF].pDesPayload = (UINT *)USB1ConfigDesc;
+ break;
+ default:
+ //unhandled descriptor. set length to 0
+ pktSize = 0;
+ break;
+ } // Endswitch
+
+ //zero length means a valid descriptor was not found.
+ if(pktSize == 0)
+ { //unhandled descriptor. send a STALL PID
+ pDCProps->pUSBRegs->ENDPTCTRLX[USB_ENDPOINT_0] |= BIT0; //set the RX EP0 STALL bit (RXS)
+ return;
+ }
+
+ //add EP0 TX dTD
+ pktSize = (pSetupPacket->wLength < pktSize) ? pSetupPacket->wLength : pktSize;
+ USB2D_EndpointTransmit(pDCProps, USB_ENDPOINT_0, USB_IN, (UINT)payload, pktSize);
+
+ //add EP0 RX dTD: size = 0, this is for the status OUT token
+ USB2D_EndpointTransmit(pDCProps, USB_ENDPOINT_0, USB_OUT, 0, 0);
+
+ return;
+}
+void USB2D_SetAddress(P_DC_Properties_T pDCProps, P_XLLP_USB_SETUP_DATA_T pSetupPacket)
+{
+ //store the address value (and set the Advance bit)
+ pDCProps->pUSBRegs->DEVICE_ADDR = (pSetupPacket->wValue << 25) | BIT24;
+
+ //send a zero length pckt to finish the Set Address
+ USB2D_EndpointTransmit(pDCProps, USB_ENDPOINT_0, USB_IN, 0, 0);
+
+}
+
+void USB2D_GetStatus(P_DC_Properties_T pDCProps, P_XLLP_USB_SETUP_DATA_T pSetupPacket)
+{
+ UINT value;
+
+ //Reply with a "Self Powered" status
+ value = 0x00000001;
+ USB2D_EndpointTransmit(pDCProps, USB_ENDPOINT_0, USB_IN, (UINT)&value, 2);
+
+ //add EP0 RX dTD: size = 0, this is for the status OUT token
+ USB2D_EndpointTransmit(pDCProps, USB_ENDPOINT_0, USB_OUT, 0, 0);
+
+}
+
+void USB2D_SetConfig(P_DC_Properties_T pDCProps, P_XLLP_USB_SETUP_DATA_T pSetupPacket)
+{
+ P_USBAPI_T p_usb;
+
+ //send a zero length pckt to finish the Set Config
+ USB2D_EndpointTransmit(pDCProps, USB_ENDPOINT_0, USB_IN, 0, 0);
+
+#if BOOTROM
+ //bootrom: check DOWNLOAD DISABLE fuse before allowing EP1 and 2 to be setup
+ if(GetTBREnvStruct()->Fuses.bits.Download_Disable)
+ return;
+#endif
+
+ //set the packet size based on speed: HI 512, FULL 64
+ p_usb = GetUSBAPIhandle_InterruptNum(pDCProps->InterruptNum);
+ if(p_usb != NULL)
+ {
+ p_usb->maxpacketsize = (pDCProps->pUSBRegs->PORTSC & BIT27) ? 512 : 64;
+
+ //set the packet size based on speed: HI 512, FULL 64
+ //GetUSBAPIhandle_InterruptNum(pDCProps->InterruptNum)->maxpacketsize = (pDCProps->pUSBRegs->PORTSC & BIT27) ? 512 : 64;
+
+ //enable EP's based on the Config Table
+ USB2D_Endpoint_Setup(pDCProps, USB_ENDPOINT_B, USB_OUT, USB_BULK);
+ USB2D_Endpoint_Setup(pDCProps, USB_ENDPOINT_A, USB_IN, USB_BULK);
+
+ //prime EP2 for Preamble
+ USB2D_EndpointTransmit( pDCProps,
+ USB_ENDPOINT_B,
+ USB_OUT,
+ (UINT)pDCProps->BufferSpace,
+ //GetUSBAPIhandle_InterruptNum(pDCProps->InterruptNum)->maxpacketsize);
+ p_usb->maxpacketsize);
+ }
+}
+
+
+//Vendor Request Setup Packet
+void USB2D_VendorRequest(P_DC_Properties_T pDCProps, P_XLLP_USB_SETUP_DATA_T pSetupPacket)
+{
+ UCHAR * NoVendorString = "NoVendorString";
+ UINT pktSize, retval;
+ void * pPayload;
+
+ retval = FindVendorRequestInTIM (pSetupPacket->bRequest, pSetupPacket->bmRequestType, (UINT *)&pPayload, &pktSize);
+
+ if(retval != NoError)
+ {
+ pktSize = 15;//sizeof(ci2NoVendorString);
+ pPayload = NoVendorString;
+ }
+
+ pktSize = (pSetupPacket->wLength < pktSize) ? pSetupPacket->wLength : pktSize;
+
+ //add EP0 TX dTD
+ pktSize = (pSetupPacket->wLength < pktSize) ? pSetupPacket->wLength : pktSize;
+ USB2D_EndpointTransmit(pDCProps, USB_ENDPOINT_0, USB_IN, (UINT)pPayload, pktSize);
+
+ //add EP0 RX dTD: size = 0, this is for the status OUT token
+ USB2D_EndpointTransmit(pDCProps, USB_ENDPOINT_0, USB_OUT, 0, 0);
+
+ return;
+}
+
+
+