blob: 106e91ae5dc2bf27384181eafe2d6ffdfc0204d0 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/******************************************************************************
2 *
3 * (C)Copyright 2013 Marvell. All Rights Reserved.
4 *
5 * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MARVELL.
6 * The copyright notice above does not evidence any actual or intended
7 * publication of such source code.
8 * This Module contains Proprietary Information of Marvell and should be
9 * treated as Confidential.
10 * The information in this file is provided for the exclusive use of the
11 * licensees of Marvell.
12 * Such users have the right to use, modify, and incorporate this code into
13 * products for purposes authorized by the license agreement provided they
14 * include this notice and the associated copyright notice with any such
15 * product.
16 * The information in this file is provided "AS IS" without warranty.
17 *
18 ******************************************************************************/
19
20
21#include "Typedef.h"
22#include "misc.h"
23#include "usb_descriptors.h"
24#include "usbdefs.h"
25#include "usb2_main.h"
26#include "usb2_enumeration.h"
27#include "usbapi.h"
28
29#if BOOTROM
30#include "Bootrom.h"
31#endif
32
33//these are allocated in UsbDescriptors.c
34extern OPT_USB_DESCRIPTOR_LOADS USBDescriptors[NUM_USB_DESCRIPTORS];
35extern CHAR USB2DevQualDesc[];
36extern CHAR USB1ConfigDesc[];
37extern UINT_T USBStringIndexTable[MAX_USB_STRINGS];
38extern void USB2D_VendorRequest(P_DC_Properties_T pDCProps, P_XLLP_USB_SETUP_DATA_T pSetupPacket);
39
40void USB2D_EnumerationHandler(P_DC_Properties_T pDCProps, P_XLLP_USB_SETUP_DATA_T pSetupPacket)
41{
42 switch (pSetupPacket->bmRequestType & 0x60)
43 {
44 case STANDARD_REQ:
45 switch (pSetupPacket->bRequest)
46 {
47 case REQ_GET_STATUS:
48 USB2D_GetStatus(pDCProps, pSetupPacket);
49 break;
50// case REQ_CLEAR_FEATURE:
51// mvUsbCh9ClearFeature(handle, setup, &ci_otg_setupPacket);
52// break;
53// case REQ_SET_FEATURE:
54// mvUsbCh9SetFeature(handle, setup, &ci_otg_setupPacket);
55// break;
56 case REQ_SET_ADDRESS:
57 USB2D_SetAddress(pDCProps, pSetupPacket);
58 break;
59 case REQ_GET_DESCRIPTOR:
60 USB2D_GetDescriptor(pDCProps, pSetupPacket);
61 break;
62// case REQ_SET_DESCRIPTOR:
63// mvUsbCh9SetDescriptior(handle, setup, &ci_otg_setupPacket);
64// break;
65// case REQ_GET_CONFIGURATION:
66// mvUsbCh9GetConfig(handle, setup, &ci_otg_setupPacket);
67// break;
68 case REQ_SET_CONFIGURATION:
69 USB2D_SetConfig(pDCProps, pSetupPacket);
70 break;
71// case REQ_GET_INTERFACE:
72// mvUsbCh9GetInterface(handle, setup, &ci_otg_setupPacket);
73// break;
74// case REQ_SET_INTERFACE:
75// mvUsbCh9SetInterface(handle, setup, &ci_otg_setupPacket);
76// break;
77 default:
78 //unhandled descriptor. send a STALL PID
79 pDCProps->pUSBRegs->ENDPTCTRLX[USB_ENDPOINT_0] |= BIT0; //set the RX EP0 STALL bit (RXS)
80 break;
81 } // Endswitch
82 break;
83 case VENDOR_REQ:
84 USB2D_VendorRequest(pDCProps, pSetupPacket);
85 break;
86 default:
87 //unhandled descriptor. send a STALL PID
88 pDCProps->pUSBRegs->ENDPTCTRLX[USB_ENDPOINT_0] |= BIT0; //set the RX EP0 STALL bit (RXS)
89 break;
90 } //Endswitch
91}
92
93void USB2D_GetDescriptor(P_DC_Properties_T pDCProps, P_XLLP_USB_SETUP_DATA_T pSetupPacket)
94{
95 UINT pktSize, stringLength, stringIndex;
96 UCHAR *payload = "UNHANDLED";
97
98 // Load the appropriate string depending on the descriptor requested
99 switch (pSetupPacket->wValue >> 8)
100 {
101 case DESC_TYPE_DEVICE:
102 pktSize = USBDescriptors[USB_DEVICE_DESCRIPTOR & 0xFF].DesSize;
103 payload = (UCHAR*)(USBDescriptors[USB_DEVICE_DESCRIPTOR & 0xFF].pDesPayload);
104 break;
105 case DESC_TYPE_CONFIG:
106 pktSize = USBDescriptors[USB_CONFIG_DESCRIPTOR & 0xFF].DesSize;
107 payload = (UCHAR*)(USBDescriptors[USB_CONFIG_DESCRIPTOR & 0xFF].pDesPayload);
108 break;
109 case DESC_TYPE_STRING:
110 stringIndex = ((pSetupPacket->wValue) & 0xFF);
111 // Bounds protection
112 if (stringIndex >= MAX_USB_STRINGS)
113 {
114 stringLength = (pSetupPacket->wLength);
115 if (stringLength > USBDescriptors[USB_DEFAULT_STRING_DESCRIPTOR & 0xFF].DesSize)
116 pktSize = USBDescriptors[USB_DEFAULT_STRING_DESCRIPTOR & 0xFF].DesSize;
117 else
118 pktSize = stringLength;
119 payload =(UCHAR*)(USBDescriptors[USB_DEFAULT_STRING_DESCRIPTOR & 0xFF].pDesPayload);
120 break;
121 }
122 switch (USBStringIndexTable[stringIndex])
123 {
124 case USB_LANGUAGE_STRING_DESCRIPTOR:
125 case USB_MANUFACTURER_STRING_DESCRIPTOR:
126 case USB_PRODUCT_STRING_DESCRIPTOR:
127 case USB_SERIAL_STRING_DESCRIPTOR:
128 case USB_INTERFACE_STRING_DESCRIPTOR:
129 case USB_DEFAULT_STRING_DESCRIPTOR:
130 stringLength = (pSetupPacket->wLength);
131 if (stringLength > USBDescriptors[USBStringIndexTable[stringIndex] & 0xFF].DesSize)
132 pktSize = USBDescriptors[USBStringIndexTable[stringIndex] & 0xFF].DesSize;
133 else
134 pktSize = stringLength;
135 payload = (UCHAR*)(USBDescriptors[USBStringIndexTable[stringIndex] & 0xFF].pDesPayload);
136 break;
137 default:
138 //unhandled descriptor. set length to 0
139 pktSize = 0;
140 break;
141 }
142 break; // from DESC_TYPE_STRING
143 case DESC_TYPE_INTERFACE:
144 pktSize = USBDescriptors[USB_INTERFACE_DESCRIPTOR & 0xFF].DesSize;
145 payload = (UCHAR*)(USBDescriptors[USB_INTERFACE_DESCRIPTOR & 0xFF].pDesPayload);
146 break;
147 case DESC_TYPE_ENDPOINT:
148 pktSize = USBDescriptors[USB_ENDPOINT_DESCRIPTOR & 0xFF].DesSize;
149 payload = (UCHAR*)(USBDescriptors[USB_ENDPOINT_DESCRIPTOR & 0xFF].pDesPayload);
150 break;
151 case DESC_TYPE_QUALIFIER:
152 //getting this request means the host wants us to run at FULL speed...
153 pktSize = USB2DevQualDesc[0]; //bLength field
154 payload = (UCHAR*) USB2DevQualDesc;
155 //overwrite the CONFIG descriptor to point to the FULL speed version
156 USBDescriptors[USB_CONFIG_DESCRIPTOR & 0xFF].DesSize = (USB1ConfigDesc[2]) + (USB1ConfigDesc[3] << 8); //LSB + MSB
157 USBDescriptors[USB_CONFIG_DESCRIPTOR & 0xFF].pDesPayload = (UINT *)USB1ConfigDesc;
158 break;
159 default:
160 //unhandled descriptor. set length to 0
161 pktSize = 0;
162 break;
163 } // Endswitch
164
165 //zero length means a valid descriptor was not found.
166 if(pktSize == 0)
167 { //unhandled descriptor. send a STALL PID
168 pDCProps->pUSBRegs->ENDPTCTRLX[USB_ENDPOINT_0] |= BIT0; //set the RX EP0 STALL bit (RXS)
169 return;
170 }
171
172 //add EP0 TX dTD
173 pktSize = (pSetupPacket->wLength < pktSize) ? pSetupPacket->wLength : pktSize;
174 USB2D_EndpointTransmit(pDCProps, USB_ENDPOINT_0, USB_IN, (UINT)payload, pktSize);
175
176 //add EP0 RX dTD: size = 0, this is for the status OUT token
177 USB2D_EndpointTransmit(pDCProps, USB_ENDPOINT_0, USB_OUT, 0, 0);
178
179 return;
180}
181void USB2D_SetAddress(P_DC_Properties_T pDCProps, P_XLLP_USB_SETUP_DATA_T pSetupPacket)
182{
183 //store the address value (and set the Advance bit)
184 pDCProps->pUSBRegs->DEVICE_ADDR = (pSetupPacket->wValue << 25) | BIT24;
185
186 //send a zero length pckt to finish the Set Address
187 USB2D_EndpointTransmit(pDCProps, USB_ENDPOINT_0, USB_IN, 0, 0);
188
189}
190
191void USB2D_GetStatus(P_DC_Properties_T pDCProps, P_XLLP_USB_SETUP_DATA_T pSetupPacket)
192{
193 UINT value;
194
195 //Reply with a "Self Powered" status
196 value = 0x00000001;
197 USB2D_EndpointTransmit(pDCProps, USB_ENDPOINT_0, USB_IN, (UINT)&value, 2);
198
199 //add EP0 RX dTD: size = 0, this is for the status OUT token
200 USB2D_EndpointTransmit(pDCProps, USB_ENDPOINT_0, USB_OUT, 0, 0);
201
202}
203
204void USB2D_SetConfig(P_DC_Properties_T pDCProps, P_XLLP_USB_SETUP_DATA_T pSetupPacket)
205{
206 P_USBAPI_T p_usb;
207
208 //send a zero length pckt to finish the Set Config
209 USB2D_EndpointTransmit(pDCProps, USB_ENDPOINT_0, USB_IN, 0, 0);
210
211#if BOOTROM
212 //bootrom: check DOWNLOAD DISABLE fuse before allowing EP1 and 2 to be setup
213 if(GetTBREnvStruct()->Fuses.bits.Download_Disable)
214 return;
215#endif
216
217 //set the packet size based on speed: HI 512, FULL 64
218 p_usb = GetUSBAPIhandle_InterruptNum(pDCProps->InterruptNum);
219 if(p_usb != NULL)
220 {
221 p_usb->maxpacketsize = (pDCProps->pUSBRegs->PORTSC & BIT27) ? 512 : 64;
222
223 //set the packet size based on speed: HI 512, FULL 64
224 //GetUSBAPIhandle_InterruptNum(pDCProps->InterruptNum)->maxpacketsize = (pDCProps->pUSBRegs->PORTSC & BIT27) ? 512 : 64;
225
226 //enable EP's based on the Config Table
227 USB2D_Endpoint_Setup(pDCProps, USB_ENDPOINT_B, USB_OUT, USB_BULK);
228 USB2D_Endpoint_Setup(pDCProps, USB_ENDPOINT_A, USB_IN, USB_BULK);
229
230 //prime EP2 for Preamble
231 USB2D_EndpointTransmit( pDCProps,
232 USB_ENDPOINT_B,
233 USB_OUT,
234 (UINT)pDCProps->BufferSpace,
235 //GetUSBAPIhandle_InterruptNum(pDCProps->InterruptNum)->maxpacketsize);
236 p_usb->maxpacketsize);
237 }
238}
239
240
241//Vendor Request Setup Packet
242void USB2D_VendorRequest(P_DC_Properties_T pDCProps, P_XLLP_USB_SETUP_DATA_T pSetupPacket)
243{
244 UCHAR * NoVendorString = "NoVendorString";
245 UINT pktSize, retval;
246 void * pPayload;
247
248 retval = FindVendorRequestInTIM (pSetupPacket->bRequest, pSetupPacket->bmRequestType, (UINT *)&pPayload, &pktSize);
249
250 if(retval != NoError)
251 {
252 pktSize = 15;//sizeof(ci2NoVendorString);
253 pPayload = NoVendorString;
254 }
255
256 pktSize = (pSetupPacket->wLength < pktSize) ? pSetupPacket->wLength : pktSize;
257
258 //add EP0 TX dTD
259 pktSize = (pSetupPacket->wLength < pktSize) ? pSetupPacket->wLength : pktSize;
260 USB2D_EndpointTransmit(pDCProps, USB_ENDPOINT_0, USB_IN, (UINT)pPayload, pktSize);
261
262 //add EP0 RX dTD: size = 0, this is for the status OUT token
263 USB2D_EndpointTransmit(pDCProps, USB_ENDPOINT_0, USB_OUT, 0, 0);
264
265 return;
266}
267
268
269