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