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;

+}

+

+

+