blob: ecaa659d204516a6fa926114deb27f98aa81b9df [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#include "snps_usb.h"
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);
39extern UINT_T USB2D_Get_Speed_Mode(void);
40
41UINT usbstatus_value = 0x00000001;
42void USB2D_EnumerationHandler(P_DC_Properties_T pDCProps, P_XLLP_USB_SETUP_DATA_T pSetupPacket)
43{
44 switch ((pSetupPacket->bmRequestType & 0x60) >> 5)
45 {
46 case STANDARD_REQ:
47 switch (pSetupPacket->bRequest)
48 {
49 case REQ_GET_STATUS:
50 USB2D_GetStatus(pDCProps, pSetupPacket);
51 break;
52// case REQ_CLEAR_FEATURE:
53// mvUsbCh9ClearFeature(handle, setup, &ci_otg_setupPacket);
54// break;
55// case REQ_SET_FEATURE:
56// mvUsbCh9SetFeature(handle, setup, &ci_otg_setupPacket);
57// break;
58 case REQ_SET_ADDRESS:
59 USB2D_SetAddress(pDCProps, pSetupPacket);
60 break;
61 case REQ_GET_DESCRIPTOR:
62 USB2D_GetDescriptor(pDCProps, pSetupPacket);
63 break;
64// case REQ_SET_DESCRIPTOR:
65// mvUsbCh9SetDescriptior(handle, setup, &ci_otg_setupPacket);
66// break;
67// case REQ_GET_CONFIGURATION:
68// mvUsbCh9GetConfig(handle, setup, &ci_otg_setupPacket);
69// break;
70 case REQ_SET_CONFIGURATION:
71 USB2D_SetConfig(pDCProps, pSetupPacket);
72 break;
73// case REQ_GET_INTERFACE:
74// mvUsbCh9GetInterface(handle, setup, &ci_otg_setupPacket);
75// break;
76// case REQ_SET_INTERFACE:
77// mvUsbCh9SetInterface(handle, setup, &ci_otg_setupPacket);
78// break;
79 default:
80 //unhandled descriptor. send a STALL PID
81 USB2D_EP0_STALL_AND_RESTART(pDCProps);
82 break;
83 } // Endswitch
84 break;
85 case VENDOR_REQ:
86 USB2D_VendorRequest(pDCProps, pSetupPacket);
87 break;
88 default:
89 //unhandled descriptor. send a STALL PID
90 USB2D_EP0_STALL_AND_RESTART(pDCProps);
91 break;
92 } //Endswitch
93}
94
95void USB2D_GetDescriptor(P_DC_Properties_T pDCProps, P_XLLP_USB_SETUP_DATA_T pSetupPacket)
96{
97 UINT pktSize, stringLength, stringIndex;
98 UCHAR *payload = "UNHANDLED";
99
100 // Load the appropriate string depending on the descriptor requested
101 switch (pSetupPacket->wValue >> 8)
102 {
103 case DESC_TYPE_DEVICE:
104 pktSize = USBDescriptors[USB_DEVICE_DESCRIPTOR & 0xFF].DesSize;
105 payload = (UCHAR*)(USBDescriptors[USB_DEVICE_DESCRIPTOR & 0xFF].pDesPayload);
106 break;
107 case DESC_TYPE_CONFIG:
108 pktSize = USBDescriptors[USB_CONFIG_DESCRIPTOR & 0xFF].DesSize;
109 payload = (UCHAR*)(USBDescriptors[USB_CONFIG_DESCRIPTOR & 0xFF].pDesPayload);
110 break;
111 case DESC_TYPE_STRING:
112 stringIndex = ((pSetupPacket->wValue) & 0xFF);
113 // Bounds protection
114 if (stringIndex >= MAX_USB_STRINGS)
115 {
116 stringLength = (pSetupPacket->wLength);
117 if (stringLength > USBDescriptors[USB_DEFAULT_STRING_DESCRIPTOR & 0xFF].DesSize)
118 pktSize = USBDescriptors[USB_DEFAULT_STRING_DESCRIPTOR & 0xFF].DesSize;
119 else
120 pktSize = stringLength;
121 payload =(UCHAR*)(USBDescriptors[USB_DEFAULT_STRING_DESCRIPTOR & 0xFF].pDesPayload);
122 break;
123 }
124 switch (USBStringIndexTable[stringIndex])
125 {
126 case USB_LANGUAGE_STRING_DESCRIPTOR:
127 case USB_MANUFACTURER_STRING_DESCRIPTOR:
128 case USB_PRODUCT_STRING_DESCRIPTOR:
129 case USB_SERIAL_STRING_DESCRIPTOR:
130 case USB_INTERFACE_STRING_DESCRIPTOR:
131 case USB_DEFAULT_STRING_DESCRIPTOR:
132 stringLength = (pSetupPacket->wLength);
133 if (stringLength > USBDescriptors[USBStringIndexTable[stringIndex] & 0xFF].DesSize)
134 pktSize = USBDescriptors[USBStringIndexTable[stringIndex] & 0xFF].DesSize;
135 else
136 pktSize = stringLength;
137 payload = (UCHAR*)(USBDescriptors[USBStringIndexTable[stringIndex] & 0xFF].pDesPayload);
138 break;
139 default:
140 //unhandled descriptor. set length to 0
141 pktSize = 0;
142 break;
143 }
144 break; // from DESC_TYPE_STRING
145 case DESC_TYPE_INTERFACE:
146 pktSize = USBDescriptors[USB_INTERFACE_DESCRIPTOR & 0xFF].DesSize;
147 payload = (UCHAR*)(USBDescriptors[USB_INTERFACE_DESCRIPTOR & 0xFF].pDesPayload);
148 break;
149 case DESC_TYPE_ENDPOINT:
150 pktSize = USBDescriptors[USB_ENDPOINT_DESCRIPTOR & 0xFF].DesSize;
151 payload = (UCHAR*)(USBDescriptors[USB_ENDPOINT_DESCRIPTOR & 0xFF].pDesPayload);
152 break;
153 case DESC_TYPE_QUALIFIER:
154 //getting this request means the host wants us to run at FULL speed...
155 pktSize = USB2DevQualDesc[0]; //bLength field
156 payload = (UCHAR*) USB2DevQualDesc;
157 //overwrite the CONFIG descriptor to point to the FULL speed version
158 USBDescriptors[USB_CONFIG_DESCRIPTOR & 0xFF].DesSize = (USB1ConfigDesc[2]) + (USB1ConfigDesc[3] << 8); //LSB + MSB
159 USBDescriptors[USB_CONFIG_DESCRIPTOR & 0xFF].pDesPayload = (UINT8_T *)USB1ConfigDesc;
160 break;
161 default:
162 //unhandled descriptor. set length to 0
163 pktSize = 0;
164 break;
165 } // Endswitch
166
167 //zero length means a valid descriptor was not found.
168 if(pktSize == 0)
169 { //unhandled descriptor. send a STALL PID
170 USB2D_EP0_STALL_AND_RESTART(pDCProps);
171 return;
172 }
173
174 //add EP0 TX dTD
175 pktSize = (pSetupPacket->wLength < pktSize) ? pSetupPacket->wLength : pktSize;
176 USB2D_Endpoint0Transmit(pDCProps, USB_ENDPOINT_0, USB_IN, (UINT)(payload), pktSize);
177
178 //add EP0 RX dTD: size = 0, this is for the status OUT token
179 //USB2D_Endpoint0Transmit(pDCProps, USB_ENDPOINT_0, USB_OUT, 0, 0);
180
181 return;
182}
183void USB2D_SetAddress(P_DC_Properties_T pDCProps, P_XLLP_USB_SETUP_DATA_T pSetupPacket)
184{
185 //store the address value (and set the Advance bit)
186 //pDCProps->pUSBRegs->DEVICE_ADDR = (pSetupPacket->wValue << 25) | BIT24;
187 USB2D_Set_Addr(pSetupPacket->wValue);
188 pDCProps->dev_addr = pSetupPacket->wValue;
189
190 //send a zero length pckt to finish the Set Address
191 USB2D_Endpoint0Transmit(pDCProps, USB_ENDPOINT_0, USB_IN, 0, 0);
192
193 if (pSetupPacket->wValue)
194 pDCProps->dev_state = USB_STATE_ADDRESS;
195 else
196 pDCProps->dev_state = USB_STATE_DEFAULT;
197}
198
199void USB2D_GetStatus(P_DC_Properties_T pDCProps, P_XLLP_USB_SETUP_DATA_T pSetupPacket)
200{
201 usbstatus_value = 0x00000001;
202
203 //Reply with a "Self Powered" status
204 USB2D_Endpoint0Transmit(pDCProps, USB_ENDPOINT_0, USB_IN, (UINT)(&usbstatus_value), 2);
205
206 //add EP0 RX dTD: size = 0, this is for the status OUT token
207 //USB2D_Endpoint0Transmit(pDCProps, USB_ENDPOINT_0, USB_OUT, 0, 0);
208
209}
210
211void USB2D_SetConfig(P_DC_Properties_T pDCProps, P_XLLP_USB_SETUP_DATA_T pSetupPacket)
212{
213 P_USBAPI_T p_usb;
214
215 //send a zero length pckt to finish the Set Config
216 USB2D_Endpoint0Transmit(pDCProps, USB_ENDPOINT_0, USB_IN, 0, 0);
217
218#if BOOTROM
219 //bootrom: check DOWNLOAD DISABLE fuse before allowing EP1 and 2 to be setup
220 if(GetTBREnvStruct()->Fuses.bits.Download_Disable)
221 return;
222#endif
223
224 //set the packet size based on speed: HI 512, FULL 64
225 p_usb = GetUSBAPIhandle_InterruptNum(pDCProps->InterruptNum);
226 if(p_usb != NULL)
227 {
228#if 0
229 p_usb->maxpacketsize = (pDCProps->pUSBRegs->PORTSC & BIT27) ? 512 : 64;
230#endif
231 if (USB_MODE_FS == USB2D_Get_Speed_Mode())
232 p_usb->maxpacketsize = 64;
233 else
234 p_usb->maxpacketsize = 512;
235
236 //set the packet size based on speed: HI 512, FULL 64
237 //GetUSBAPIhandle_InterruptNum(pDCProps->InterruptNum)->maxpacketsize = (pDCProps->pUSBRegs->PORTSC & BIT27) ? 512 : 64;
238
239 //enable EP's based on the Config Table
240 USB2D_Endpoint_Setup(pDCProps, USB_ENDPOINT_A, USB_OUT, USB_BULK);
241 USB2D_Endpoint_Setup(pDCProps, USB_ENDPOINT_A, USB_IN, USB_BULK);
242 pDCProps->dev_state = USB_STATE_CONFIGURED;
243 //prime EP2 for Preamble
244 USB2D_EndpointTransmit( pDCProps,
245 USB_ENDPOINT_A,
246 USB_OUT,
247 (UINT)(pDCProps->BufferSpace),
248 p_usb->maxpacketsize);
249 }
250}
251
252
253//Vendor Request Setup Packet
254void USB2D_VendorRequest(P_DC_Properties_T pDCProps, P_XLLP_USB_SETUP_DATA_T pSetupPacket)
255{
256 UCHAR * NoVendorString = "NoVendorString";
257 UINT pktSize, retval;
258 void * pPayload;
259
260 retval = FindVendorRequestInTIM (pSetupPacket->bRequest, pSetupPacket->bmRequestType, (UINT *)&pPayload, &pktSize);
261
262 if(retval != NoError)
263 {
264 pktSize = 15;//sizeof(ci2NoVendorString);
265 pPayload = NoVendorString;
266 }
267
268 pktSize = (pSetupPacket->wLength < pktSize) ? pSetupPacket->wLength : pktSize;
269
270 //add EP0 TX dTD
271 pktSize = (pSetupPacket->wLength < pktSize) ? pSetupPacket->wLength : pktSize;
272 USB2D_Endpoint0Transmit(pDCProps, USB_ENDPOINT_0, USB_IN, (UINT)(pPayload), pktSize);
273 //add EP0 RX dTD: size = 0, this is for the status OUT token
274 //USB2D_Endpoint0Transmit(pDCProps, USB_ENDPOINT_0, USB_OUT, 0, 0);
275
276 return;
277}
278
279
280