xref: /OK3568_Linux_fs/kernel/drivers/usb/mtu3/mtu3_gadget_ep0.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * mtu3_gadget_ep0.c - MediaTek USB3 DRD peripheral driver ep0 handling
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (c) 2016 MediaTek Inc.
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Author:  Chunfeng.Yun <chunfeng.yun@mediatek.com>
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include <linux/iopoll.h>
11*4882a593Smuzhiyun #include <linux/usb/composite.h>
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #include "mtu3.h"
14*4882a593Smuzhiyun #include "mtu3_debug.h"
15*4882a593Smuzhiyun #include "mtu3_trace.h"
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun /* ep0 is always mtu3->in_eps[0] */
18*4882a593Smuzhiyun #define	next_ep0_request(mtu)	next_request((mtu)->ep0)
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun /* for high speed test mode; see USB 2.0 spec 7.1.20 */
21*4882a593Smuzhiyun static const u8 mtu3_test_packet[53] = {
22*4882a593Smuzhiyun 	/* implicit SYNC then DATA0 to start */
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun 	/* JKJKJKJK x9 */
25*4882a593Smuzhiyun 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
26*4882a593Smuzhiyun 	/* JJKKJJKK x8 */
27*4882a593Smuzhiyun 	0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
28*4882a593Smuzhiyun 	/* JJJJKKKK x8 */
29*4882a593Smuzhiyun 	0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
30*4882a593Smuzhiyun 	/* JJJJJJJKKKKKKK x8 */
31*4882a593Smuzhiyun 	0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
32*4882a593Smuzhiyun 	/* JJJJJJJK x8 */
33*4882a593Smuzhiyun 	0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd,
34*4882a593Smuzhiyun 	/* JKKKKKKK x10, JK */
35*4882a593Smuzhiyun 	0xfc, 0x7e, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0x7e,
36*4882a593Smuzhiyun 	/* implicit CRC16 then EOP to end */
37*4882a593Smuzhiyun };
38*4882a593Smuzhiyun 
decode_ep0_state(struct mtu3 * mtu)39*4882a593Smuzhiyun static char *decode_ep0_state(struct mtu3 *mtu)
40*4882a593Smuzhiyun {
41*4882a593Smuzhiyun 	switch (mtu->ep0_state) {
42*4882a593Smuzhiyun 	case MU3D_EP0_STATE_SETUP:
43*4882a593Smuzhiyun 		return "SETUP";
44*4882a593Smuzhiyun 	case MU3D_EP0_STATE_TX:
45*4882a593Smuzhiyun 		return "IN";
46*4882a593Smuzhiyun 	case MU3D_EP0_STATE_RX:
47*4882a593Smuzhiyun 		return "OUT";
48*4882a593Smuzhiyun 	case MU3D_EP0_STATE_TX_END:
49*4882a593Smuzhiyun 		return "TX-END";
50*4882a593Smuzhiyun 	case MU3D_EP0_STATE_STALL:
51*4882a593Smuzhiyun 		return "STALL";
52*4882a593Smuzhiyun 	default:
53*4882a593Smuzhiyun 		return "??";
54*4882a593Smuzhiyun 	}
55*4882a593Smuzhiyun }
56*4882a593Smuzhiyun 
ep0_req_giveback(struct mtu3 * mtu,struct usb_request * req)57*4882a593Smuzhiyun static void ep0_req_giveback(struct mtu3 *mtu, struct usb_request *req)
58*4882a593Smuzhiyun {
59*4882a593Smuzhiyun 	mtu3_req_complete(mtu->ep0, req, 0);
60*4882a593Smuzhiyun }
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun static int
forward_to_driver(struct mtu3 * mtu,const struct usb_ctrlrequest * setup)63*4882a593Smuzhiyun forward_to_driver(struct mtu3 *mtu, const struct usb_ctrlrequest *setup)
64*4882a593Smuzhiyun __releases(mtu->lock)
65*4882a593Smuzhiyun __acquires(mtu->lock)
66*4882a593Smuzhiyun {
67*4882a593Smuzhiyun 	int ret;
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun 	if (!mtu->gadget_driver)
70*4882a593Smuzhiyun 		return -EOPNOTSUPP;
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun 	spin_unlock(&mtu->lock);
73*4882a593Smuzhiyun 	ret = mtu->gadget_driver->setup(&mtu->g, setup);
74*4882a593Smuzhiyun 	spin_lock(&mtu->lock);
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun 	dev_dbg(mtu->dev, "%s ret %d\n", __func__, ret);
77*4882a593Smuzhiyun 	return ret;
78*4882a593Smuzhiyun }
79*4882a593Smuzhiyun 
ep0_write_fifo(struct mtu3_ep * mep,const u8 * src,u16 len)80*4882a593Smuzhiyun static void ep0_write_fifo(struct mtu3_ep *mep, const u8 *src, u16 len)
81*4882a593Smuzhiyun {
82*4882a593Smuzhiyun 	void __iomem *fifo = mep->mtu->mac_base + U3D_FIFO0;
83*4882a593Smuzhiyun 	u16 index = 0;
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun 	dev_dbg(mep->mtu->dev, "%s: ep%din, len=%d, buf=%p\n",
86*4882a593Smuzhiyun 		__func__, mep->epnum, len, src);
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun 	if (len >= 4) {
89*4882a593Smuzhiyun 		iowrite32_rep(fifo, src, len >> 2);
90*4882a593Smuzhiyun 		index = len & ~0x03;
91*4882a593Smuzhiyun 	}
92*4882a593Smuzhiyun 	if (len & 0x02) {
93*4882a593Smuzhiyun 		writew(*(u16 *)&src[index], fifo);
94*4882a593Smuzhiyun 		index += 2;
95*4882a593Smuzhiyun 	}
96*4882a593Smuzhiyun 	if (len & 0x01)
97*4882a593Smuzhiyun 		writeb(src[index], fifo);
98*4882a593Smuzhiyun }
99*4882a593Smuzhiyun 
ep0_read_fifo(struct mtu3_ep * mep,u8 * dst,u16 len)100*4882a593Smuzhiyun static void ep0_read_fifo(struct mtu3_ep *mep, u8 *dst, u16 len)
101*4882a593Smuzhiyun {
102*4882a593Smuzhiyun 	void __iomem *fifo = mep->mtu->mac_base + U3D_FIFO0;
103*4882a593Smuzhiyun 	u32 value;
104*4882a593Smuzhiyun 	u16 index = 0;
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun 	dev_dbg(mep->mtu->dev, "%s: ep%dout len=%d buf=%p\n",
107*4882a593Smuzhiyun 		 __func__, mep->epnum, len, dst);
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun 	if (len >= 4) {
110*4882a593Smuzhiyun 		ioread32_rep(fifo, dst, len >> 2);
111*4882a593Smuzhiyun 		index = len & ~0x03;
112*4882a593Smuzhiyun 	}
113*4882a593Smuzhiyun 	if (len & 0x3) {
114*4882a593Smuzhiyun 		value = readl(fifo);
115*4882a593Smuzhiyun 		memcpy(&dst[index], &value, len & 0x3);
116*4882a593Smuzhiyun 	}
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun }
119*4882a593Smuzhiyun 
ep0_load_test_packet(struct mtu3 * mtu)120*4882a593Smuzhiyun static void ep0_load_test_packet(struct mtu3 *mtu)
121*4882a593Smuzhiyun {
122*4882a593Smuzhiyun 	/*
123*4882a593Smuzhiyun 	 * because the length of test packet is less than max packet of HS ep0,
124*4882a593Smuzhiyun 	 * write it into fifo directly.
125*4882a593Smuzhiyun 	 */
126*4882a593Smuzhiyun 	ep0_write_fifo(mtu->ep0, mtu3_test_packet, sizeof(mtu3_test_packet));
127*4882a593Smuzhiyun }
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun /*
130*4882a593Smuzhiyun  * A. send STALL for setup transfer without data stage:
131*4882a593Smuzhiyun  *		set SENDSTALL and SETUPPKTRDY at the same time;
132*4882a593Smuzhiyun  * B. send STALL for other cases:
133*4882a593Smuzhiyun  *		set SENDSTALL only.
134*4882a593Smuzhiyun  */
ep0_stall_set(struct mtu3_ep * mep0,bool set,u32 pktrdy)135*4882a593Smuzhiyun static void ep0_stall_set(struct mtu3_ep *mep0, bool set, u32 pktrdy)
136*4882a593Smuzhiyun {
137*4882a593Smuzhiyun 	struct mtu3 *mtu = mep0->mtu;
138*4882a593Smuzhiyun 	void __iomem *mbase = mtu->mac_base;
139*4882a593Smuzhiyun 	u32 csr;
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun 	/* EP0_SENTSTALL is W1C */
142*4882a593Smuzhiyun 	csr = mtu3_readl(mbase, U3D_EP0CSR) & EP0_W1C_BITS;
143*4882a593Smuzhiyun 	if (set)
144*4882a593Smuzhiyun 		csr |= EP0_SENDSTALL | pktrdy;
145*4882a593Smuzhiyun 	else
146*4882a593Smuzhiyun 		csr = (csr & ~EP0_SENDSTALL) | EP0_SENTSTALL;
147*4882a593Smuzhiyun 	mtu3_writel(mtu->mac_base, U3D_EP0CSR, csr);
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 	mtu->delayed_status = false;
150*4882a593Smuzhiyun 	mtu->ep0_state = MU3D_EP0_STATE_SETUP;
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun 	dev_dbg(mtu->dev, "ep0: %s STALL, ep0_state: %s\n",
153*4882a593Smuzhiyun 		set ? "SEND" : "CLEAR", decode_ep0_state(mtu));
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun 
ep0_do_status_stage(struct mtu3 * mtu)156*4882a593Smuzhiyun static void ep0_do_status_stage(struct mtu3 *mtu)
157*4882a593Smuzhiyun {
158*4882a593Smuzhiyun 	void __iomem *mbase = mtu->mac_base;
159*4882a593Smuzhiyun 	u32 value;
160*4882a593Smuzhiyun 
161*4882a593Smuzhiyun 	value = mtu3_readl(mbase, U3D_EP0CSR) & EP0_W1C_BITS;
162*4882a593Smuzhiyun 	mtu3_writel(mbase, U3D_EP0CSR, value | EP0_SETUPPKTRDY | EP0_DATAEND);
163*4882a593Smuzhiyun }
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun static int ep0_queue(struct mtu3_ep *mep0, struct mtu3_request *mreq);
166*4882a593Smuzhiyun 
ep0_dummy_complete(struct usb_ep * ep,struct usb_request * req)167*4882a593Smuzhiyun static void ep0_dummy_complete(struct usb_ep *ep, struct usb_request *req)
168*4882a593Smuzhiyun {}
169*4882a593Smuzhiyun 
ep0_set_sel_complete(struct usb_ep * ep,struct usb_request * req)170*4882a593Smuzhiyun static void ep0_set_sel_complete(struct usb_ep *ep, struct usb_request *req)
171*4882a593Smuzhiyun {
172*4882a593Smuzhiyun 	struct mtu3_request *mreq;
173*4882a593Smuzhiyun 	struct mtu3 *mtu;
174*4882a593Smuzhiyun 	struct usb_set_sel_req sel;
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun 	memcpy(&sel, req->buf, sizeof(sel));
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun 	mreq = to_mtu3_request(req);
179*4882a593Smuzhiyun 	mtu = mreq->mtu;
180*4882a593Smuzhiyun 	dev_dbg(mtu->dev, "u1sel:%d, u1pel:%d, u2sel:%d, u2pel:%d\n",
181*4882a593Smuzhiyun 		sel.u1_sel, sel.u1_pel, sel.u2_sel, sel.u2_pel);
182*4882a593Smuzhiyun }
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun /* queue data stage to handle 6 byte SET_SEL request */
ep0_set_sel(struct mtu3 * mtu,struct usb_ctrlrequest * setup)185*4882a593Smuzhiyun static int ep0_set_sel(struct mtu3 *mtu, struct usb_ctrlrequest *setup)
186*4882a593Smuzhiyun {
187*4882a593Smuzhiyun 	int ret;
188*4882a593Smuzhiyun 	u16 length = le16_to_cpu(setup->wLength);
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun 	if (unlikely(length != 6)) {
191*4882a593Smuzhiyun 		dev_err(mtu->dev, "%s wrong wLength:%d\n",
192*4882a593Smuzhiyun 			__func__, length);
193*4882a593Smuzhiyun 		return -EINVAL;
194*4882a593Smuzhiyun 	}
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun 	mtu->ep0_req.mep = mtu->ep0;
197*4882a593Smuzhiyun 	mtu->ep0_req.request.length = 6;
198*4882a593Smuzhiyun 	mtu->ep0_req.request.buf = mtu->setup_buf;
199*4882a593Smuzhiyun 	mtu->ep0_req.request.complete = ep0_set_sel_complete;
200*4882a593Smuzhiyun 	ret = ep0_queue(mtu->ep0, &mtu->ep0_req);
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun 	return ret < 0 ? ret : 1;
203*4882a593Smuzhiyun }
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun static int
ep0_get_status(struct mtu3 * mtu,const struct usb_ctrlrequest * setup)206*4882a593Smuzhiyun ep0_get_status(struct mtu3 *mtu, const struct usb_ctrlrequest *setup)
207*4882a593Smuzhiyun {
208*4882a593Smuzhiyun 	struct mtu3_ep *mep = NULL;
209*4882a593Smuzhiyun 	int handled = 1;
210*4882a593Smuzhiyun 	u8 result[2] = {0, 0};
211*4882a593Smuzhiyun 	u8 epnum = 0;
212*4882a593Smuzhiyun 	int is_in;
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun 	switch (setup->bRequestType & USB_RECIP_MASK) {
215*4882a593Smuzhiyun 	case USB_RECIP_DEVICE:
216*4882a593Smuzhiyun 		result[0] = mtu->is_self_powered << USB_DEVICE_SELF_POWERED;
217*4882a593Smuzhiyun 		result[0] |= mtu->may_wakeup << USB_DEVICE_REMOTE_WAKEUP;
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun 		if (mtu->g.speed >= USB_SPEED_SUPER) {
220*4882a593Smuzhiyun 			result[0] |= mtu->u1_enable << USB_DEV_STAT_U1_ENABLED;
221*4882a593Smuzhiyun 			result[0] |= mtu->u2_enable << USB_DEV_STAT_U2_ENABLED;
222*4882a593Smuzhiyun 		}
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun 		dev_dbg(mtu->dev, "%s result=%x, U1=%x, U2=%x\n", __func__,
225*4882a593Smuzhiyun 			result[0], mtu->u1_enable, mtu->u2_enable);
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun 		break;
228*4882a593Smuzhiyun 	case USB_RECIP_INTERFACE:
229*4882a593Smuzhiyun 		break;
230*4882a593Smuzhiyun 	case USB_RECIP_ENDPOINT:
231*4882a593Smuzhiyun 		epnum = (u8) le16_to_cpu(setup->wIndex);
232*4882a593Smuzhiyun 		is_in = epnum & USB_DIR_IN;
233*4882a593Smuzhiyun 		epnum &= USB_ENDPOINT_NUMBER_MASK;
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 		if (epnum >= mtu->num_eps) {
236*4882a593Smuzhiyun 			handled = -EINVAL;
237*4882a593Smuzhiyun 			break;
238*4882a593Smuzhiyun 		}
239*4882a593Smuzhiyun 		if (!epnum)
240*4882a593Smuzhiyun 			break;
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun 		mep = (is_in ? mtu->in_eps : mtu->out_eps) + epnum;
243*4882a593Smuzhiyun 		if (!mep->desc) {
244*4882a593Smuzhiyun 			handled = -EINVAL;
245*4882a593Smuzhiyun 			break;
246*4882a593Smuzhiyun 		}
247*4882a593Smuzhiyun 		if (mep->flags & MTU3_EP_STALL)
248*4882a593Smuzhiyun 			result[0] |= 1 << USB_ENDPOINT_HALT;
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun 		break;
251*4882a593Smuzhiyun 	default:
252*4882a593Smuzhiyun 		/* class, vendor, etc ... delegate */
253*4882a593Smuzhiyun 		handled = 0;
254*4882a593Smuzhiyun 		break;
255*4882a593Smuzhiyun 	}
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun 	if (handled > 0) {
258*4882a593Smuzhiyun 		int ret;
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun 		/* prepare a data stage for GET_STATUS */
261*4882a593Smuzhiyun 		dev_dbg(mtu->dev, "get_status=%x\n", *(u16 *)result);
262*4882a593Smuzhiyun 		memcpy(mtu->setup_buf, result, sizeof(result));
263*4882a593Smuzhiyun 		mtu->ep0_req.mep = mtu->ep0;
264*4882a593Smuzhiyun 		mtu->ep0_req.request.length = 2;
265*4882a593Smuzhiyun 		mtu->ep0_req.request.buf = &mtu->setup_buf;
266*4882a593Smuzhiyun 		mtu->ep0_req.request.complete = ep0_dummy_complete;
267*4882a593Smuzhiyun 		ret = ep0_queue(mtu->ep0, &mtu->ep0_req);
268*4882a593Smuzhiyun 		if (ret < 0)
269*4882a593Smuzhiyun 			handled = ret;
270*4882a593Smuzhiyun 	}
271*4882a593Smuzhiyun 	return handled;
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun 
handle_test_mode(struct mtu3 * mtu,struct usb_ctrlrequest * setup)274*4882a593Smuzhiyun static int handle_test_mode(struct mtu3 *mtu, struct usb_ctrlrequest *setup)
275*4882a593Smuzhiyun {
276*4882a593Smuzhiyun 	void __iomem *mbase = mtu->mac_base;
277*4882a593Smuzhiyun 	int handled = 1;
278*4882a593Smuzhiyun 	u32 value;
279*4882a593Smuzhiyun 
280*4882a593Smuzhiyun 	switch (le16_to_cpu(setup->wIndex) >> 8) {
281*4882a593Smuzhiyun 	case USB_TEST_J:
282*4882a593Smuzhiyun 		dev_dbg(mtu->dev, "USB_TEST_J\n");
283*4882a593Smuzhiyun 		mtu->test_mode_nr = TEST_J_MODE;
284*4882a593Smuzhiyun 		break;
285*4882a593Smuzhiyun 	case USB_TEST_K:
286*4882a593Smuzhiyun 		dev_dbg(mtu->dev, "USB_TEST_K\n");
287*4882a593Smuzhiyun 		mtu->test_mode_nr = TEST_K_MODE;
288*4882a593Smuzhiyun 		break;
289*4882a593Smuzhiyun 	case USB_TEST_SE0_NAK:
290*4882a593Smuzhiyun 		dev_dbg(mtu->dev, "USB_TEST_SE0_NAK\n");
291*4882a593Smuzhiyun 		mtu->test_mode_nr = TEST_SE0_NAK_MODE;
292*4882a593Smuzhiyun 		break;
293*4882a593Smuzhiyun 	case USB_TEST_PACKET:
294*4882a593Smuzhiyun 		dev_dbg(mtu->dev, "USB_TEST_PACKET\n");
295*4882a593Smuzhiyun 		mtu->test_mode_nr = TEST_PACKET_MODE;
296*4882a593Smuzhiyun 		break;
297*4882a593Smuzhiyun 	default:
298*4882a593Smuzhiyun 		handled = -EINVAL;
299*4882a593Smuzhiyun 		goto out;
300*4882a593Smuzhiyun 	}
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun 	mtu->test_mode = true;
303*4882a593Smuzhiyun 
304*4882a593Smuzhiyun 	/* no TX completion interrupt, and need restart platform after test */
305*4882a593Smuzhiyun 	if (mtu->test_mode_nr == TEST_PACKET_MODE)
306*4882a593Smuzhiyun 		ep0_load_test_packet(mtu);
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun 	/* send status before entering test mode. */
309*4882a593Smuzhiyun 	ep0_do_status_stage(mtu);
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun 	/* wait for ACK status sent by host */
312*4882a593Smuzhiyun 	readl_poll_timeout_atomic(mbase + U3D_EP0CSR, value,
313*4882a593Smuzhiyun 			!(value & EP0_DATAEND), 100, 5000);
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun 	mtu3_writel(mbase, U3D_USB2_TEST_MODE, mtu->test_mode_nr);
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun 	mtu->ep0_state = MU3D_EP0_STATE_SETUP;
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun out:
320*4882a593Smuzhiyun 	return handled;
321*4882a593Smuzhiyun }
322*4882a593Smuzhiyun 
ep0_handle_feature_dev(struct mtu3 * mtu,struct usb_ctrlrequest * setup,bool set)323*4882a593Smuzhiyun static int ep0_handle_feature_dev(struct mtu3 *mtu,
324*4882a593Smuzhiyun 		struct usb_ctrlrequest *setup, bool set)
325*4882a593Smuzhiyun {
326*4882a593Smuzhiyun 	void __iomem *mbase = mtu->mac_base;
327*4882a593Smuzhiyun 	int handled = -EINVAL;
328*4882a593Smuzhiyun 	u32 lpc;
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun 	switch (le16_to_cpu(setup->wValue)) {
331*4882a593Smuzhiyun 	case USB_DEVICE_REMOTE_WAKEUP:
332*4882a593Smuzhiyun 		mtu->may_wakeup = !!set;
333*4882a593Smuzhiyun 		handled = 1;
334*4882a593Smuzhiyun 		break;
335*4882a593Smuzhiyun 	case USB_DEVICE_TEST_MODE:
336*4882a593Smuzhiyun 		if (!set || (mtu->g.speed != USB_SPEED_HIGH) ||
337*4882a593Smuzhiyun 			(le16_to_cpu(setup->wIndex) & 0xff))
338*4882a593Smuzhiyun 			break;
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun 		handled = handle_test_mode(mtu, setup);
341*4882a593Smuzhiyun 		break;
342*4882a593Smuzhiyun 	case USB_DEVICE_U1_ENABLE:
343*4882a593Smuzhiyun 		if (mtu->g.speed < USB_SPEED_SUPER ||
344*4882a593Smuzhiyun 		    mtu->g.state != USB_STATE_CONFIGURED)
345*4882a593Smuzhiyun 			break;
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun 		lpc = mtu3_readl(mbase, U3D_LINK_POWER_CONTROL);
348*4882a593Smuzhiyun 		if (set)
349*4882a593Smuzhiyun 			lpc |= SW_U1_REQUEST_ENABLE;
350*4882a593Smuzhiyun 		else
351*4882a593Smuzhiyun 			lpc &= ~SW_U1_REQUEST_ENABLE;
352*4882a593Smuzhiyun 		mtu3_writel(mbase, U3D_LINK_POWER_CONTROL, lpc);
353*4882a593Smuzhiyun 
354*4882a593Smuzhiyun 		mtu->u1_enable = !!set;
355*4882a593Smuzhiyun 		handled = 1;
356*4882a593Smuzhiyun 		break;
357*4882a593Smuzhiyun 	case USB_DEVICE_U2_ENABLE:
358*4882a593Smuzhiyun 		if (mtu->g.speed < USB_SPEED_SUPER ||
359*4882a593Smuzhiyun 		    mtu->g.state != USB_STATE_CONFIGURED)
360*4882a593Smuzhiyun 			break;
361*4882a593Smuzhiyun 
362*4882a593Smuzhiyun 		lpc = mtu3_readl(mbase, U3D_LINK_POWER_CONTROL);
363*4882a593Smuzhiyun 		if (set)
364*4882a593Smuzhiyun 			lpc |= SW_U2_REQUEST_ENABLE;
365*4882a593Smuzhiyun 		else
366*4882a593Smuzhiyun 			lpc &= ~SW_U2_REQUEST_ENABLE;
367*4882a593Smuzhiyun 		mtu3_writel(mbase, U3D_LINK_POWER_CONTROL, lpc);
368*4882a593Smuzhiyun 
369*4882a593Smuzhiyun 		mtu->u2_enable = !!set;
370*4882a593Smuzhiyun 		handled = 1;
371*4882a593Smuzhiyun 		break;
372*4882a593Smuzhiyun 	default:
373*4882a593Smuzhiyun 		handled = -EINVAL;
374*4882a593Smuzhiyun 		break;
375*4882a593Smuzhiyun 	}
376*4882a593Smuzhiyun 	return handled;
377*4882a593Smuzhiyun }
378*4882a593Smuzhiyun 
ep0_handle_feature(struct mtu3 * mtu,struct usb_ctrlrequest * setup,bool set)379*4882a593Smuzhiyun static int ep0_handle_feature(struct mtu3 *mtu,
380*4882a593Smuzhiyun 		struct usb_ctrlrequest *setup, bool set)
381*4882a593Smuzhiyun {
382*4882a593Smuzhiyun 	struct mtu3_ep *mep;
383*4882a593Smuzhiyun 	int handled = -EINVAL;
384*4882a593Smuzhiyun 	int is_in;
385*4882a593Smuzhiyun 	u16 value;
386*4882a593Smuzhiyun 	u16 index;
387*4882a593Smuzhiyun 	u8 epnum;
388*4882a593Smuzhiyun 
389*4882a593Smuzhiyun 	value = le16_to_cpu(setup->wValue);
390*4882a593Smuzhiyun 	index = le16_to_cpu(setup->wIndex);
391*4882a593Smuzhiyun 
392*4882a593Smuzhiyun 	switch (setup->bRequestType & USB_RECIP_MASK) {
393*4882a593Smuzhiyun 	case USB_RECIP_DEVICE:
394*4882a593Smuzhiyun 		handled = ep0_handle_feature_dev(mtu, setup, set);
395*4882a593Smuzhiyun 		break;
396*4882a593Smuzhiyun 	case USB_RECIP_INTERFACE:
397*4882a593Smuzhiyun 		/* superspeed only */
398*4882a593Smuzhiyun 		if (value == USB_INTRF_FUNC_SUSPEND &&
399*4882a593Smuzhiyun 		    mtu->g.speed >= USB_SPEED_SUPER) {
400*4882a593Smuzhiyun 			/*
401*4882a593Smuzhiyun 			 * forward the request because function drivers
402*4882a593Smuzhiyun 			 * should handle it
403*4882a593Smuzhiyun 			 */
404*4882a593Smuzhiyun 			handled = 0;
405*4882a593Smuzhiyun 		}
406*4882a593Smuzhiyun 		break;
407*4882a593Smuzhiyun 	case USB_RECIP_ENDPOINT:
408*4882a593Smuzhiyun 		epnum = index & USB_ENDPOINT_NUMBER_MASK;
409*4882a593Smuzhiyun 		if (epnum == 0 || epnum >= mtu->num_eps ||
410*4882a593Smuzhiyun 			value != USB_ENDPOINT_HALT)
411*4882a593Smuzhiyun 			break;
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun 		is_in = index & USB_DIR_IN;
414*4882a593Smuzhiyun 		mep = (is_in ? mtu->in_eps : mtu->out_eps) + epnum;
415*4882a593Smuzhiyun 		if (!mep->desc)
416*4882a593Smuzhiyun 			break;
417*4882a593Smuzhiyun 
418*4882a593Smuzhiyun 		handled = 1;
419*4882a593Smuzhiyun 		/* ignore request if endpoint is wedged */
420*4882a593Smuzhiyun 		if (mep->flags & MTU3_EP_WEDGE)
421*4882a593Smuzhiyun 			break;
422*4882a593Smuzhiyun 
423*4882a593Smuzhiyun 		mtu3_ep_stall_set(mep, set);
424*4882a593Smuzhiyun 		break;
425*4882a593Smuzhiyun 	default:
426*4882a593Smuzhiyun 		/* class, vendor, etc ... delegate */
427*4882a593Smuzhiyun 		handled = 0;
428*4882a593Smuzhiyun 		break;
429*4882a593Smuzhiyun 	}
430*4882a593Smuzhiyun 	return handled;
431*4882a593Smuzhiyun }
432*4882a593Smuzhiyun 
433*4882a593Smuzhiyun /*
434*4882a593Smuzhiyun  * handle all control requests can be handled
435*4882a593Smuzhiyun  * returns:
436*4882a593Smuzhiyun  *	negative errno - error happened
437*4882a593Smuzhiyun  *	zero - need delegate SETUP to gadget driver
438*4882a593Smuzhiyun  *	positive - already handled
439*4882a593Smuzhiyun  */
handle_standard_request(struct mtu3 * mtu,struct usb_ctrlrequest * setup)440*4882a593Smuzhiyun static int handle_standard_request(struct mtu3 *mtu,
441*4882a593Smuzhiyun 			  struct usb_ctrlrequest *setup)
442*4882a593Smuzhiyun {
443*4882a593Smuzhiyun 	void __iomem *mbase = mtu->mac_base;
444*4882a593Smuzhiyun 	enum usb_device_state state = mtu->g.state;
445*4882a593Smuzhiyun 	int handled = -EINVAL;
446*4882a593Smuzhiyun 	u32 dev_conf;
447*4882a593Smuzhiyun 	u16 value;
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun 	value = le16_to_cpu(setup->wValue);
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun 	/* the gadget driver handles everything except what we must handle */
452*4882a593Smuzhiyun 	switch (setup->bRequest) {
453*4882a593Smuzhiyun 	case USB_REQ_SET_ADDRESS:
454*4882a593Smuzhiyun 		/* change it after the status stage */
455*4882a593Smuzhiyun 		mtu->address = (u8) (value & 0x7f);
456*4882a593Smuzhiyun 		dev_dbg(mtu->dev, "set address to 0x%x\n", mtu->address);
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun 		dev_conf = mtu3_readl(mbase, U3D_DEVICE_CONF);
459*4882a593Smuzhiyun 		dev_conf &= ~DEV_ADDR_MSK;
460*4882a593Smuzhiyun 		dev_conf |= DEV_ADDR(mtu->address);
461*4882a593Smuzhiyun 		mtu3_writel(mbase, U3D_DEVICE_CONF, dev_conf);
462*4882a593Smuzhiyun 
463*4882a593Smuzhiyun 		if (mtu->address)
464*4882a593Smuzhiyun 			usb_gadget_set_state(&mtu->g, USB_STATE_ADDRESS);
465*4882a593Smuzhiyun 		else
466*4882a593Smuzhiyun 			usb_gadget_set_state(&mtu->g, USB_STATE_DEFAULT);
467*4882a593Smuzhiyun 
468*4882a593Smuzhiyun 		handled = 1;
469*4882a593Smuzhiyun 		break;
470*4882a593Smuzhiyun 	case USB_REQ_SET_CONFIGURATION:
471*4882a593Smuzhiyun 		if (state == USB_STATE_ADDRESS) {
472*4882a593Smuzhiyun 			usb_gadget_set_state(&mtu->g,
473*4882a593Smuzhiyun 					USB_STATE_CONFIGURED);
474*4882a593Smuzhiyun 		} else if (state == USB_STATE_CONFIGURED) {
475*4882a593Smuzhiyun 			/*
476*4882a593Smuzhiyun 			 * USB2 spec sec 9.4.7, if wValue is 0 then dev
477*4882a593Smuzhiyun 			 * is moved to addressed state
478*4882a593Smuzhiyun 			 */
479*4882a593Smuzhiyun 			if (!value)
480*4882a593Smuzhiyun 				usb_gadget_set_state(&mtu->g,
481*4882a593Smuzhiyun 						USB_STATE_ADDRESS);
482*4882a593Smuzhiyun 		}
483*4882a593Smuzhiyun 		handled = 0;
484*4882a593Smuzhiyun 		break;
485*4882a593Smuzhiyun 	case USB_REQ_CLEAR_FEATURE:
486*4882a593Smuzhiyun 		handled = ep0_handle_feature(mtu, setup, 0);
487*4882a593Smuzhiyun 		break;
488*4882a593Smuzhiyun 	case USB_REQ_SET_FEATURE:
489*4882a593Smuzhiyun 		handled = ep0_handle_feature(mtu, setup, 1);
490*4882a593Smuzhiyun 		break;
491*4882a593Smuzhiyun 	case USB_REQ_GET_STATUS:
492*4882a593Smuzhiyun 		handled = ep0_get_status(mtu, setup);
493*4882a593Smuzhiyun 		break;
494*4882a593Smuzhiyun 	case USB_REQ_SET_SEL:
495*4882a593Smuzhiyun 		handled = ep0_set_sel(mtu, setup);
496*4882a593Smuzhiyun 		break;
497*4882a593Smuzhiyun 	case USB_REQ_SET_ISOCH_DELAY:
498*4882a593Smuzhiyun 		handled = 1;
499*4882a593Smuzhiyun 		break;
500*4882a593Smuzhiyun 	default:
501*4882a593Smuzhiyun 		/* delegate SET_CONFIGURATION, etc */
502*4882a593Smuzhiyun 		handled = 0;
503*4882a593Smuzhiyun 	}
504*4882a593Smuzhiyun 
505*4882a593Smuzhiyun 	return handled;
506*4882a593Smuzhiyun }
507*4882a593Smuzhiyun 
508*4882a593Smuzhiyun /* receive an data packet (OUT) */
ep0_rx_state(struct mtu3 * mtu)509*4882a593Smuzhiyun static void ep0_rx_state(struct mtu3 *mtu)
510*4882a593Smuzhiyun {
511*4882a593Smuzhiyun 	struct mtu3_request *mreq;
512*4882a593Smuzhiyun 	struct usb_request *req;
513*4882a593Smuzhiyun 	void __iomem *mbase = mtu->mac_base;
514*4882a593Smuzhiyun 	u32 maxp;
515*4882a593Smuzhiyun 	u32 csr;
516*4882a593Smuzhiyun 	u16 count = 0;
517*4882a593Smuzhiyun 
518*4882a593Smuzhiyun 	dev_dbg(mtu->dev, "%s\n", __func__);
519*4882a593Smuzhiyun 
520*4882a593Smuzhiyun 	csr = mtu3_readl(mbase, U3D_EP0CSR) & EP0_W1C_BITS;
521*4882a593Smuzhiyun 	mreq = next_ep0_request(mtu);
522*4882a593Smuzhiyun 	req = &mreq->request;
523*4882a593Smuzhiyun 
524*4882a593Smuzhiyun 	/* read packet and ack; or stall because of gadget driver bug */
525*4882a593Smuzhiyun 	if (req) {
526*4882a593Smuzhiyun 		void *buf = req->buf + req->actual;
527*4882a593Smuzhiyun 		unsigned int len = req->length - req->actual;
528*4882a593Smuzhiyun 
529*4882a593Smuzhiyun 		/* read the buffer */
530*4882a593Smuzhiyun 		count = mtu3_readl(mbase, U3D_RXCOUNT0);
531*4882a593Smuzhiyun 		if (count > len) {
532*4882a593Smuzhiyun 			req->status = -EOVERFLOW;
533*4882a593Smuzhiyun 			count = len;
534*4882a593Smuzhiyun 		}
535*4882a593Smuzhiyun 		ep0_read_fifo(mtu->ep0, buf, count);
536*4882a593Smuzhiyun 		req->actual += count;
537*4882a593Smuzhiyun 		csr |= EP0_RXPKTRDY;
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun 		maxp = mtu->g.ep0->maxpacket;
540*4882a593Smuzhiyun 		if (count < maxp || req->actual == req->length) {
541*4882a593Smuzhiyun 			mtu->ep0_state = MU3D_EP0_STATE_SETUP;
542*4882a593Smuzhiyun 			dev_dbg(mtu->dev, "ep0 state: %s\n",
543*4882a593Smuzhiyun 				decode_ep0_state(mtu));
544*4882a593Smuzhiyun 
545*4882a593Smuzhiyun 			csr |= EP0_DATAEND;
546*4882a593Smuzhiyun 		} else {
547*4882a593Smuzhiyun 			req = NULL;
548*4882a593Smuzhiyun 		}
549*4882a593Smuzhiyun 	} else {
550*4882a593Smuzhiyun 		csr |= EP0_RXPKTRDY | EP0_SENDSTALL;
551*4882a593Smuzhiyun 		dev_dbg(mtu->dev, "%s: SENDSTALL\n", __func__);
552*4882a593Smuzhiyun 	}
553*4882a593Smuzhiyun 
554*4882a593Smuzhiyun 	mtu3_writel(mbase, U3D_EP0CSR, csr);
555*4882a593Smuzhiyun 
556*4882a593Smuzhiyun 	/* give back the request if have received all data */
557*4882a593Smuzhiyun 	if (req)
558*4882a593Smuzhiyun 		ep0_req_giveback(mtu, req);
559*4882a593Smuzhiyun 
560*4882a593Smuzhiyun }
561*4882a593Smuzhiyun 
562*4882a593Smuzhiyun /* transmitting to the host (IN) */
ep0_tx_state(struct mtu3 * mtu)563*4882a593Smuzhiyun static void ep0_tx_state(struct mtu3 *mtu)
564*4882a593Smuzhiyun {
565*4882a593Smuzhiyun 	struct mtu3_request *mreq = next_ep0_request(mtu);
566*4882a593Smuzhiyun 	struct usb_request *req;
567*4882a593Smuzhiyun 	u32 csr;
568*4882a593Smuzhiyun 	u8 *src;
569*4882a593Smuzhiyun 	u32 count;
570*4882a593Smuzhiyun 	u32 maxp;
571*4882a593Smuzhiyun 
572*4882a593Smuzhiyun 	dev_dbg(mtu->dev, "%s\n", __func__);
573*4882a593Smuzhiyun 
574*4882a593Smuzhiyun 	if (!mreq)
575*4882a593Smuzhiyun 		return;
576*4882a593Smuzhiyun 
577*4882a593Smuzhiyun 	maxp = mtu->g.ep0->maxpacket;
578*4882a593Smuzhiyun 	req = &mreq->request;
579*4882a593Smuzhiyun 
580*4882a593Smuzhiyun 	/* load the data */
581*4882a593Smuzhiyun 	src = (u8 *)req->buf + req->actual;
582*4882a593Smuzhiyun 	count = min(maxp, req->length - req->actual);
583*4882a593Smuzhiyun 	if (count)
584*4882a593Smuzhiyun 		ep0_write_fifo(mtu->ep0, src, count);
585*4882a593Smuzhiyun 
586*4882a593Smuzhiyun 	dev_dbg(mtu->dev, "%s act=%d, len=%d, cnt=%d, maxp=%d zero=%d\n",
587*4882a593Smuzhiyun 		 __func__, req->actual, req->length, count, maxp, req->zero);
588*4882a593Smuzhiyun 
589*4882a593Smuzhiyun 	req->actual += count;
590*4882a593Smuzhiyun 
591*4882a593Smuzhiyun 	if ((count < maxp)
592*4882a593Smuzhiyun 		|| ((req->actual == req->length) && !req->zero))
593*4882a593Smuzhiyun 		mtu->ep0_state = MU3D_EP0_STATE_TX_END;
594*4882a593Smuzhiyun 
595*4882a593Smuzhiyun 	/* send it out, triggering a "txpktrdy cleared" irq */
596*4882a593Smuzhiyun 	csr = mtu3_readl(mtu->mac_base, U3D_EP0CSR) & EP0_W1C_BITS;
597*4882a593Smuzhiyun 	mtu3_writel(mtu->mac_base, U3D_EP0CSR, csr | EP0_TXPKTRDY);
598*4882a593Smuzhiyun 
599*4882a593Smuzhiyun 	dev_dbg(mtu->dev, "%s ep0csr=0x%x\n", __func__,
600*4882a593Smuzhiyun 		mtu3_readl(mtu->mac_base, U3D_EP0CSR));
601*4882a593Smuzhiyun }
602*4882a593Smuzhiyun 
ep0_read_setup(struct mtu3 * mtu,struct usb_ctrlrequest * setup)603*4882a593Smuzhiyun static void ep0_read_setup(struct mtu3 *mtu, struct usb_ctrlrequest *setup)
604*4882a593Smuzhiyun {
605*4882a593Smuzhiyun 	struct mtu3_request *mreq;
606*4882a593Smuzhiyun 	u32 count;
607*4882a593Smuzhiyun 	u32 csr;
608*4882a593Smuzhiyun 
609*4882a593Smuzhiyun 	csr = mtu3_readl(mtu->mac_base, U3D_EP0CSR) & EP0_W1C_BITS;
610*4882a593Smuzhiyun 	count = mtu3_readl(mtu->mac_base, U3D_RXCOUNT0);
611*4882a593Smuzhiyun 
612*4882a593Smuzhiyun 	ep0_read_fifo(mtu->ep0, (u8 *)setup, count);
613*4882a593Smuzhiyun 
614*4882a593Smuzhiyun 	dev_dbg(mtu->dev, "SETUP req%02x.%02x v%04x i%04x l%04x\n",
615*4882a593Smuzhiyun 		 setup->bRequestType, setup->bRequest,
616*4882a593Smuzhiyun 		 le16_to_cpu(setup->wValue), le16_to_cpu(setup->wIndex),
617*4882a593Smuzhiyun 		 le16_to_cpu(setup->wLength));
618*4882a593Smuzhiyun 
619*4882a593Smuzhiyun 	/* clean up any leftover transfers */
620*4882a593Smuzhiyun 	mreq = next_ep0_request(mtu);
621*4882a593Smuzhiyun 	if (mreq)
622*4882a593Smuzhiyun 		ep0_req_giveback(mtu, &mreq->request);
623*4882a593Smuzhiyun 
624*4882a593Smuzhiyun 	if (le16_to_cpu(setup->wLength) == 0) {
625*4882a593Smuzhiyun 		;	/* no data stage, nothing to do */
626*4882a593Smuzhiyun 	} else if (setup->bRequestType & USB_DIR_IN) {
627*4882a593Smuzhiyun 		mtu3_writel(mtu->mac_base, U3D_EP0CSR,
628*4882a593Smuzhiyun 			csr | EP0_SETUPPKTRDY | EP0_DPHTX);
629*4882a593Smuzhiyun 		mtu->ep0_state = MU3D_EP0_STATE_TX;
630*4882a593Smuzhiyun 	} else {
631*4882a593Smuzhiyun 		mtu3_writel(mtu->mac_base, U3D_EP0CSR,
632*4882a593Smuzhiyun 			(csr | EP0_SETUPPKTRDY) & (~EP0_DPHTX));
633*4882a593Smuzhiyun 		mtu->ep0_state = MU3D_EP0_STATE_RX;
634*4882a593Smuzhiyun 	}
635*4882a593Smuzhiyun }
636*4882a593Smuzhiyun 
ep0_handle_setup(struct mtu3 * mtu)637*4882a593Smuzhiyun static int ep0_handle_setup(struct mtu3 *mtu)
638*4882a593Smuzhiyun __releases(mtu->lock)
639*4882a593Smuzhiyun __acquires(mtu->lock)
640*4882a593Smuzhiyun {
641*4882a593Smuzhiyun 	struct usb_ctrlrequest setup;
642*4882a593Smuzhiyun 	struct mtu3_request *mreq;
643*4882a593Smuzhiyun 	int handled = 0;
644*4882a593Smuzhiyun 
645*4882a593Smuzhiyun 	ep0_read_setup(mtu, &setup);
646*4882a593Smuzhiyun 	trace_mtu3_handle_setup(&setup);
647*4882a593Smuzhiyun 
648*4882a593Smuzhiyun 	if ((setup.bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD)
649*4882a593Smuzhiyun 		handled = handle_standard_request(mtu, &setup);
650*4882a593Smuzhiyun 
651*4882a593Smuzhiyun 	dev_dbg(mtu->dev, "handled %d, ep0_state: %s\n",
652*4882a593Smuzhiyun 		 handled, decode_ep0_state(mtu));
653*4882a593Smuzhiyun 
654*4882a593Smuzhiyun 	if (handled < 0)
655*4882a593Smuzhiyun 		goto stall;
656*4882a593Smuzhiyun 	else if (handled > 0)
657*4882a593Smuzhiyun 		goto finish;
658*4882a593Smuzhiyun 
659*4882a593Smuzhiyun 	handled = forward_to_driver(mtu, &setup);
660*4882a593Smuzhiyun 	if (handled < 0) {
661*4882a593Smuzhiyun stall:
662*4882a593Smuzhiyun 		dev_dbg(mtu->dev, "%s stall (%d)\n", __func__, handled);
663*4882a593Smuzhiyun 
664*4882a593Smuzhiyun 		ep0_stall_set(mtu->ep0, true,
665*4882a593Smuzhiyun 			le16_to_cpu(setup.wLength) ? 0 : EP0_SETUPPKTRDY);
666*4882a593Smuzhiyun 
667*4882a593Smuzhiyun 		return 0;
668*4882a593Smuzhiyun 	}
669*4882a593Smuzhiyun 
670*4882a593Smuzhiyun finish:
671*4882a593Smuzhiyun 	if (mtu->test_mode) {
672*4882a593Smuzhiyun 		;	/* nothing to do */
673*4882a593Smuzhiyun 	} else if (handled == USB_GADGET_DELAYED_STATUS) {
674*4882a593Smuzhiyun 
675*4882a593Smuzhiyun 		mreq = next_ep0_request(mtu);
676*4882a593Smuzhiyun 		if (mreq) {
677*4882a593Smuzhiyun 			/* already asked us to continue delayed status */
678*4882a593Smuzhiyun 			ep0_do_status_stage(mtu);
679*4882a593Smuzhiyun 			ep0_req_giveback(mtu, &mreq->request);
680*4882a593Smuzhiyun 		} else {
681*4882a593Smuzhiyun 			/* do delayed STATUS stage till receive ep0_queue */
682*4882a593Smuzhiyun 			mtu->delayed_status = true;
683*4882a593Smuzhiyun 		}
684*4882a593Smuzhiyun 	} else if (le16_to_cpu(setup.wLength) == 0) { /* no data stage */
685*4882a593Smuzhiyun 
686*4882a593Smuzhiyun 		ep0_do_status_stage(mtu);
687*4882a593Smuzhiyun 		/* complete zlp request directly */
688*4882a593Smuzhiyun 		mreq = next_ep0_request(mtu);
689*4882a593Smuzhiyun 		if (mreq && !mreq->request.length)
690*4882a593Smuzhiyun 			ep0_req_giveback(mtu, &mreq->request);
691*4882a593Smuzhiyun 	}
692*4882a593Smuzhiyun 
693*4882a593Smuzhiyun 	return 0;
694*4882a593Smuzhiyun }
695*4882a593Smuzhiyun 
mtu3_ep0_isr(struct mtu3 * mtu)696*4882a593Smuzhiyun irqreturn_t mtu3_ep0_isr(struct mtu3 *mtu)
697*4882a593Smuzhiyun {
698*4882a593Smuzhiyun 	void __iomem *mbase = mtu->mac_base;
699*4882a593Smuzhiyun 	struct mtu3_request *mreq;
700*4882a593Smuzhiyun 	u32 int_status;
701*4882a593Smuzhiyun 	irqreturn_t ret = IRQ_NONE;
702*4882a593Smuzhiyun 	u32 csr;
703*4882a593Smuzhiyun 	u32 len;
704*4882a593Smuzhiyun 
705*4882a593Smuzhiyun 	int_status = mtu3_readl(mbase, U3D_EPISR);
706*4882a593Smuzhiyun 	int_status &= mtu3_readl(mbase, U3D_EPIER);
707*4882a593Smuzhiyun 	mtu3_writel(mbase, U3D_EPISR, int_status); /* W1C */
708*4882a593Smuzhiyun 
709*4882a593Smuzhiyun 	/* only handle ep0's */
710*4882a593Smuzhiyun 	if (!(int_status & (EP0ISR | SETUPENDISR)))
711*4882a593Smuzhiyun 		return IRQ_NONE;
712*4882a593Smuzhiyun 
713*4882a593Smuzhiyun 	/* abort current SETUP, and process new one */
714*4882a593Smuzhiyun 	if (int_status & SETUPENDISR)
715*4882a593Smuzhiyun 		mtu->ep0_state = MU3D_EP0_STATE_SETUP;
716*4882a593Smuzhiyun 
717*4882a593Smuzhiyun 	csr = mtu3_readl(mbase, U3D_EP0CSR);
718*4882a593Smuzhiyun 
719*4882a593Smuzhiyun 	dev_dbg(mtu->dev, "%s csr=0x%x\n", __func__, csr);
720*4882a593Smuzhiyun 
721*4882a593Smuzhiyun 	/* we sent a stall.. need to clear it now.. */
722*4882a593Smuzhiyun 	if (csr & EP0_SENTSTALL) {
723*4882a593Smuzhiyun 		ep0_stall_set(mtu->ep0, false, 0);
724*4882a593Smuzhiyun 		csr = mtu3_readl(mbase, U3D_EP0CSR);
725*4882a593Smuzhiyun 		ret = IRQ_HANDLED;
726*4882a593Smuzhiyun 	}
727*4882a593Smuzhiyun 	dev_dbg(mtu->dev, "ep0_state: %s\n", decode_ep0_state(mtu));
728*4882a593Smuzhiyun 	mtu3_dbg_trace(mtu->dev, "ep0_state %s", decode_ep0_state(mtu));
729*4882a593Smuzhiyun 
730*4882a593Smuzhiyun 	switch (mtu->ep0_state) {
731*4882a593Smuzhiyun 	case MU3D_EP0_STATE_TX:
732*4882a593Smuzhiyun 		/* irq on clearing txpktrdy */
733*4882a593Smuzhiyun 		if ((csr & EP0_FIFOFULL) == 0) {
734*4882a593Smuzhiyun 			ep0_tx_state(mtu);
735*4882a593Smuzhiyun 			ret = IRQ_HANDLED;
736*4882a593Smuzhiyun 		}
737*4882a593Smuzhiyun 		break;
738*4882a593Smuzhiyun 	case MU3D_EP0_STATE_RX:
739*4882a593Smuzhiyun 		/* irq on set rxpktrdy */
740*4882a593Smuzhiyun 		if (csr & EP0_RXPKTRDY) {
741*4882a593Smuzhiyun 			ep0_rx_state(mtu);
742*4882a593Smuzhiyun 			ret = IRQ_HANDLED;
743*4882a593Smuzhiyun 		}
744*4882a593Smuzhiyun 		break;
745*4882a593Smuzhiyun 	case MU3D_EP0_STATE_TX_END:
746*4882a593Smuzhiyun 		mtu3_writel(mbase, U3D_EP0CSR,
747*4882a593Smuzhiyun 			(csr & EP0_W1C_BITS) | EP0_DATAEND);
748*4882a593Smuzhiyun 
749*4882a593Smuzhiyun 		mreq = next_ep0_request(mtu);
750*4882a593Smuzhiyun 		if (mreq)
751*4882a593Smuzhiyun 			ep0_req_giveback(mtu, &mreq->request);
752*4882a593Smuzhiyun 
753*4882a593Smuzhiyun 		mtu->ep0_state = MU3D_EP0_STATE_SETUP;
754*4882a593Smuzhiyun 		ret = IRQ_HANDLED;
755*4882a593Smuzhiyun 		dev_dbg(mtu->dev, "ep0_state: %s\n", decode_ep0_state(mtu));
756*4882a593Smuzhiyun 		break;
757*4882a593Smuzhiyun 	case MU3D_EP0_STATE_SETUP:
758*4882a593Smuzhiyun 		if (!(csr & EP0_SETUPPKTRDY))
759*4882a593Smuzhiyun 			break;
760*4882a593Smuzhiyun 
761*4882a593Smuzhiyun 		len = mtu3_readl(mbase, U3D_RXCOUNT0);
762*4882a593Smuzhiyun 		if (len != 8) {
763*4882a593Smuzhiyun 			dev_err(mtu->dev, "SETUP packet len %d != 8 ?\n", len);
764*4882a593Smuzhiyun 			break;
765*4882a593Smuzhiyun 		}
766*4882a593Smuzhiyun 
767*4882a593Smuzhiyun 		ep0_handle_setup(mtu);
768*4882a593Smuzhiyun 		ret = IRQ_HANDLED;
769*4882a593Smuzhiyun 		break;
770*4882a593Smuzhiyun 	default:
771*4882a593Smuzhiyun 		/* can't happen */
772*4882a593Smuzhiyun 		ep0_stall_set(mtu->ep0, true, 0);
773*4882a593Smuzhiyun 		WARN_ON(1);
774*4882a593Smuzhiyun 		break;
775*4882a593Smuzhiyun 	}
776*4882a593Smuzhiyun 
777*4882a593Smuzhiyun 	return ret;
778*4882a593Smuzhiyun }
779*4882a593Smuzhiyun 
780*4882a593Smuzhiyun 
mtu3_ep0_enable(struct usb_ep * ep,const struct usb_endpoint_descriptor * desc)781*4882a593Smuzhiyun static int mtu3_ep0_enable(struct usb_ep *ep,
782*4882a593Smuzhiyun 	const struct usb_endpoint_descriptor *desc)
783*4882a593Smuzhiyun {
784*4882a593Smuzhiyun 	/* always enabled */
785*4882a593Smuzhiyun 	return -EINVAL;
786*4882a593Smuzhiyun }
787*4882a593Smuzhiyun 
mtu3_ep0_disable(struct usb_ep * ep)788*4882a593Smuzhiyun static int mtu3_ep0_disable(struct usb_ep *ep)
789*4882a593Smuzhiyun {
790*4882a593Smuzhiyun 	/* always enabled */
791*4882a593Smuzhiyun 	return -EINVAL;
792*4882a593Smuzhiyun }
793*4882a593Smuzhiyun 
ep0_queue(struct mtu3_ep * mep,struct mtu3_request * mreq)794*4882a593Smuzhiyun static int ep0_queue(struct mtu3_ep *mep, struct mtu3_request *mreq)
795*4882a593Smuzhiyun {
796*4882a593Smuzhiyun 	struct mtu3 *mtu = mep->mtu;
797*4882a593Smuzhiyun 
798*4882a593Smuzhiyun 	mreq->mtu = mtu;
799*4882a593Smuzhiyun 	mreq->request.actual = 0;
800*4882a593Smuzhiyun 	mreq->request.status = -EINPROGRESS;
801*4882a593Smuzhiyun 
802*4882a593Smuzhiyun 	dev_dbg(mtu->dev, "%s %s (ep0_state: %s), len#%d\n", __func__,
803*4882a593Smuzhiyun 		mep->name, decode_ep0_state(mtu), mreq->request.length);
804*4882a593Smuzhiyun 
805*4882a593Smuzhiyun 	switch (mtu->ep0_state) {
806*4882a593Smuzhiyun 	case MU3D_EP0_STATE_SETUP:
807*4882a593Smuzhiyun 	case MU3D_EP0_STATE_RX:	/* control-OUT data */
808*4882a593Smuzhiyun 	case MU3D_EP0_STATE_TX:	/* control-IN data */
809*4882a593Smuzhiyun 		break;
810*4882a593Smuzhiyun 	default:
811*4882a593Smuzhiyun 		dev_err(mtu->dev, "%s, error in ep0 state %s\n", __func__,
812*4882a593Smuzhiyun 			decode_ep0_state(mtu));
813*4882a593Smuzhiyun 		return -EINVAL;
814*4882a593Smuzhiyun 	}
815*4882a593Smuzhiyun 
816*4882a593Smuzhiyun 	if (mtu->delayed_status) {
817*4882a593Smuzhiyun 
818*4882a593Smuzhiyun 		mtu->delayed_status = false;
819*4882a593Smuzhiyun 		ep0_do_status_stage(mtu);
820*4882a593Smuzhiyun 		/* needn't giveback the request for handling delay STATUS */
821*4882a593Smuzhiyun 		return 0;
822*4882a593Smuzhiyun 	}
823*4882a593Smuzhiyun 
824*4882a593Smuzhiyun 	if (!list_empty(&mep->req_list))
825*4882a593Smuzhiyun 		return -EBUSY;
826*4882a593Smuzhiyun 
827*4882a593Smuzhiyun 	list_add_tail(&mreq->list, &mep->req_list);
828*4882a593Smuzhiyun 
829*4882a593Smuzhiyun 	/* sequence #1, IN ... start writing the data */
830*4882a593Smuzhiyun 	if (mtu->ep0_state == MU3D_EP0_STATE_TX)
831*4882a593Smuzhiyun 		ep0_tx_state(mtu);
832*4882a593Smuzhiyun 
833*4882a593Smuzhiyun 	return 0;
834*4882a593Smuzhiyun }
835*4882a593Smuzhiyun 
mtu3_ep0_queue(struct usb_ep * ep,struct usb_request * req,gfp_t gfp)836*4882a593Smuzhiyun static int mtu3_ep0_queue(struct usb_ep *ep,
837*4882a593Smuzhiyun 	struct usb_request *req, gfp_t gfp)
838*4882a593Smuzhiyun {
839*4882a593Smuzhiyun 	struct mtu3_ep *mep;
840*4882a593Smuzhiyun 	struct mtu3_request *mreq;
841*4882a593Smuzhiyun 	struct mtu3 *mtu;
842*4882a593Smuzhiyun 	unsigned long flags;
843*4882a593Smuzhiyun 	int ret = 0;
844*4882a593Smuzhiyun 
845*4882a593Smuzhiyun 	if (!ep || !req)
846*4882a593Smuzhiyun 		return -EINVAL;
847*4882a593Smuzhiyun 
848*4882a593Smuzhiyun 	mep = to_mtu3_ep(ep);
849*4882a593Smuzhiyun 	mtu = mep->mtu;
850*4882a593Smuzhiyun 	mreq = to_mtu3_request(req);
851*4882a593Smuzhiyun 
852*4882a593Smuzhiyun 	spin_lock_irqsave(&mtu->lock, flags);
853*4882a593Smuzhiyun 	ret = ep0_queue(mep, mreq);
854*4882a593Smuzhiyun 	spin_unlock_irqrestore(&mtu->lock, flags);
855*4882a593Smuzhiyun 	return ret;
856*4882a593Smuzhiyun }
857*4882a593Smuzhiyun 
mtu3_ep0_dequeue(struct usb_ep * ep,struct usb_request * req)858*4882a593Smuzhiyun static int mtu3_ep0_dequeue(struct usb_ep *ep, struct usb_request *req)
859*4882a593Smuzhiyun {
860*4882a593Smuzhiyun 	/* we just won't support this */
861*4882a593Smuzhiyun 	return -EINVAL;
862*4882a593Smuzhiyun }
863*4882a593Smuzhiyun 
mtu3_ep0_halt(struct usb_ep * ep,int value)864*4882a593Smuzhiyun static int mtu3_ep0_halt(struct usb_ep *ep, int value)
865*4882a593Smuzhiyun {
866*4882a593Smuzhiyun 	struct mtu3_ep *mep;
867*4882a593Smuzhiyun 	struct mtu3 *mtu;
868*4882a593Smuzhiyun 	unsigned long flags;
869*4882a593Smuzhiyun 	int ret = 0;
870*4882a593Smuzhiyun 
871*4882a593Smuzhiyun 	if (!ep || !value)
872*4882a593Smuzhiyun 		return -EINVAL;
873*4882a593Smuzhiyun 
874*4882a593Smuzhiyun 	mep = to_mtu3_ep(ep);
875*4882a593Smuzhiyun 	mtu = mep->mtu;
876*4882a593Smuzhiyun 
877*4882a593Smuzhiyun 	dev_dbg(mtu->dev, "%s\n", __func__);
878*4882a593Smuzhiyun 
879*4882a593Smuzhiyun 	spin_lock_irqsave(&mtu->lock, flags);
880*4882a593Smuzhiyun 
881*4882a593Smuzhiyun 	if (!list_empty(&mep->req_list)) {
882*4882a593Smuzhiyun 		ret = -EBUSY;
883*4882a593Smuzhiyun 		goto cleanup;
884*4882a593Smuzhiyun 	}
885*4882a593Smuzhiyun 
886*4882a593Smuzhiyun 	switch (mtu->ep0_state) {
887*4882a593Smuzhiyun 	/*
888*4882a593Smuzhiyun 	 * stalls are usually issued after parsing SETUP packet, either
889*4882a593Smuzhiyun 	 * directly in irq context from setup() or else later.
890*4882a593Smuzhiyun 	 */
891*4882a593Smuzhiyun 	case MU3D_EP0_STATE_TX:
892*4882a593Smuzhiyun 	case MU3D_EP0_STATE_TX_END:
893*4882a593Smuzhiyun 	case MU3D_EP0_STATE_RX:
894*4882a593Smuzhiyun 	case MU3D_EP0_STATE_SETUP:
895*4882a593Smuzhiyun 		ep0_stall_set(mtu->ep0, true, 0);
896*4882a593Smuzhiyun 		break;
897*4882a593Smuzhiyun 	default:
898*4882a593Smuzhiyun 		dev_dbg(mtu->dev, "ep0 can't halt in state %s\n",
899*4882a593Smuzhiyun 			decode_ep0_state(mtu));
900*4882a593Smuzhiyun 		ret = -EINVAL;
901*4882a593Smuzhiyun 	}
902*4882a593Smuzhiyun 
903*4882a593Smuzhiyun cleanup:
904*4882a593Smuzhiyun 	spin_unlock_irqrestore(&mtu->lock, flags);
905*4882a593Smuzhiyun 	return ret;
906*4882a593Smuzhiyun }
907*4882a593Smuzhiyun 
908*4882a593Smuzhiyun const struct usb_ep_ops mtu3_ep0_ops = {
909*4882a593Smuzhiyun 	.enable = mtu3_ep0_enable,
910*4882a593Smuzhiyun 	.disable = mtu3_ep0_disable,
911*4882a593Smuzhiyun 	.alloc_request = mtu3_alloc_request,
912*4882a593Smuzhiyun 	.free_request = mtu3_free_request,
913*4882a593Smuzhiyun 	.queue = mtu3_ep0_queue,
914*4882a593Smuzhiyun 	.dequeue = mtu3_ep0_dequeue,
915*4882a593Smuzhiyun 	.set_halt = mtu3_ep0_halt,
916*4882a593Smuzhiyun };
917