Lines Matching +full:disable +full:- +full:eop
1 // SPDX-License-Identifier: GPL-2.0
3 * mtu3_gadget_ep0.c - MediaTek USB3 DRD peripheral driver ep0 handling
17 /* ep0 is always mtu3->in_eps[0] */
18 #define next_ep0_request(mtu) next_request((mtu)->ep0)
36 /* implicit CRC16 then EOP to end */
41 switch (mtu->ep0_state) { in decode_ep0_state()
49 return "TX-END"; in decode_ep0_state()
59 mtu3_req_complete(mtu->ep0, req, 0); in ep0_req_giveback()
64 __releases(mtu->lock) in forward_to_driver()
65 __acquires(mtu->lock) in forward_to_driver()
69 if (!mtu->gadget_driver || !mtu->async_callbacks) in forward_to_driver()
70 return -EOPNOTSUPP; in forward_to_driver()
72 spin_unlock(&mtu->lock); in forward_to_driver()
73 ret = mtu->gadget_driver->setup(&mtu->g, setup); in forward_to_driver()
74 spin_lock(&mtu->lock); in forward_to_driver()
76 dev_dbg(mtu->dev, "%s ret %d\n", __func__, ret); in forward_to_driver()
82 void __iomem *fifo = mep->mtu->mac_base + U3D_FIFO0; in ep0_write_fifo()
85 dev_dbg(mep->mtu->dev, "%s: ep%din, len=%d, buf=%p\n", in ep0_write_fifo()
86 __func__, mep->epnum, len, src); in ep0_write_fifo()
102 void __iomem *fifo = mep->mtu->mac_base + U3D_FIFO0; in ep0_read_fifo()
106 dev_dbg(mep->mtu->dev, "%s: ep%dout len=%d buf=%p\n", in ep0_read_fifo()
107 __func__, mep->epnum, len, dst); in ep0_read_fifo()
126 ep0_write_fifo(mtu->ep0, mtu3_test_packet, sizeof(mtu3_test_packet)); in ep0_load_test_packet()
137 struct mtu3 *mtu = mep0->mtu; in ep0_stall_set()
138 void __iomem *mbase = mtu->mac_base; in ep0_stall_set()
147 mtu3_writel(mtu->mac_base, U3D_EP0CSR, csr); in ep0_stall_set()
149 mtu->delayed_status = false; in ep0_stall_set()
150 mtu->ep0_state = MU3D_EP0_STATE_SETUP; in ep0_stall_set()
152 dev_dbg(mtu->dev, "ep0: %s STALL, ep0_state: %s\n", in ep0_stall_set()
158 void __iomem *mbase = mtu->mac_base; in ep0_do_status_stage()
176 memcpy(&sel, req->buf, sizeof(sel)); in ep0_set_sel_complete()
179 mtu = mreq->mtu; in ep0_set_sel_complete()
180 dev_dbg(mtu->dev, "u1sel:%d, u1pel:%d, u2sel:%d, u2pel:%d\n", in ep0_set_sel_complete()
188 u16 length = le16_to_cpu(setup->wLength); in ep0_set_sel()
191 dev_err(mtu->dev, "%s wrong wLength:%d\n", in ep0_set_sel()
193 return -EINVAL; in ep0_set_sel()
196 mtu->ep0_req.mep = mtu->ep0; in ep0_set_sel()
197 mtu->ep0_req.request.length = 6; in ep0_set_sel()
198 mtu->ep0_req.request.buf = mtu->setup_buf; in ep0_set_sel()
199 mtu->ep0_req.request.complete = ep0_set_sel_complete; in ep0_set_sel()
200 ret = ep0_queue(mtu->ep0, &mtu->ep0_req); in ep0_set_sel()
214 switch (setup->bRequestType & USB_RECIP_MASK) { in ep0_get_status()
216 result[0] = mtu->is_self_powered << USB_DEVICE_SELF_POWERED; in ep0_get_status()
217 result[0] |= mtu->may_wakeup << USB_DEVICE_REMOTE_WAKEUP; in ep0_get_status()
219 if (mtu->g.speed >= USB_SPEED_SUPER) { in ep0_get_status()
220 result[0] |= mtu->u1_enable << USB_DEV_STAT_U1_ENABLED; in ep0_get_status()
221 result[0] |= mtu->u2_enable << USB_DEV_STAT_U2_ENABLED; in ep0_get_status()
224 dev_dbg(mtu->dev, "%s result=%x, U1=%x, U2=%x\n", __func__, in ep0_get_status()
225 result[0], mtu->u1_enable, mtu->u2_enable); in ep0_get_status()
233 epnum = (u8) le16_to_cpu(setup->wIndex); in ep0_get_status()
237 if (epnum >= mtu->num_eps) { in ep0_get_status()
238 handled = -EINVAL; in ep0_get_status()
244 mep = (is_in ? mtu->in_eps : mtu->out_eps) + epnum; in ep0_get_status()
245 if (!mep->desc) { in ep0_get_status()
246 handled = -EINVAL; in ep0_get_status()
249 if (mep->flags & MTU3_EP_STALL) in ep0_get_status()
263 dev_dbg(mtu->dev, "get_status=%x\n", *(u16 *)result); in ep0_get_status()
264 memcpy(mtu->setup_buf, result, sizeof(result)); in ep0_get_status()
265 mtu->ep0_req.mep = mtu->ep0; in ep0_get_status()
266 mtu->ep0_req.request.length = 2; in ep0_get_status()
267 mtu->ep0_req.request.buf = &mtu->setup_buf; in ep0_get_status()
268 mtu->ep0_req.request.complete = ep0_dummy_complete; in ep0_get_status()
269 ret = ep0_queue(mtu->ep0, &mtu->ep0_req); in ep0_get_status()
278 void __iomem *mbase = mtu->mac_base; in handle_test_mode()
282 switch (le16_to_cpu(setup->wIndex) >> 8) { in handle_test_mode()
284 dev_dbg(mtu->dev, "USB_TEST_J\n"); in handle_test_mode()
285 mtu->test_mode_nr = TEST_J_MODE; in handle_test_mode()
288 dev_dbg(mtu->dev, "USB_TEST_K\n"); in handle_test_mode()
289 mtu->test_mode_nr = TEST_K_MODE; in handle_test_mode()
292 dev_dbg(mtu->dev, "USB_TEST_SE0_NAK\n"); in handle_test_mode()
293 mtu->test_mode_nr = TEST_SE0_NAK_MODE; in handle_test_mode()
296 dev_dbg(mtu->dev, "USB_TEST_PACKET\n"); in handle_test_mode()
297 mtu->test_mode_nr = TEST_PACKET_MODE; in handle_test_mode()
300 handled = -EINVAL; in handle_test_mode()
304 mtu->test_mode = true; in handle_test_mode()
307 if (mtu->test_mode_nr == TEST_PACKET_MODE) in handle_test_mode()
317 mtu3_writel(mbase, U3D_USB2_TEST_MODE, mtu->test_mode_nr); in handle_test_mode()
319 mtu->ep0_state = MU3D_EP0_STATE_SETUP; in handle_test_mode()
328 void __iomem *mbase = mtu->mac_base; in ep0_handle_feature_dev()
329 int handled = -EINVAL; in ep0_handle_feature_dev()
332 switch (le16_to_cpu(setup->wValue)) { in ep0_handle_feature_dev()
334 mtu->may_wakeup = !!set; in ep0_handle_feature_dev()
338 if (!set || (mtu->g.speed != USB_SPEED_HIGH) || in ep0_handle_feature_dev()
339 (le16_to_cpu(setup->wIndex) & 0xff)) in ep0_handle_feature_dev()
345 if (mtu->g.speed < USB_SPEED_SUPER || in ep0_handle_feature_dev()
346 mtu->g.state != USB_STATE_CONFIGURED) in ep0_handle_feature_dev()
356 mtu->u1_enable = !!set; in ep0_handle_feature_dev()
360 if (mtu->g.speed < USB_SPEED_SUPER || in ep0_handle_feature_dev()
361 mtu->g.state != USB_STATE_CONFIGURED) in ep0_handle_feature_dev()
371 mtu->u2_enable = !!set; in ep0_handle_feature_dev()
375 handled = -EINVAL; in ep0_handle_feature_dev()
385 int handled = -EINVAL; in ep0_handle_feature()
391 value = le16_to_cpu(setup->wValue); in ep0_handle_feature()
392 index = le16_to_cpu(setup->wIndex); in ep0_handle_feature()
394 switch (setup->bRequestType & USB_RECIP_MASK) { in ep0_handle_feature()
401 mtu->g.speed >= USB_SPEED_SUPER) { in ep0_handle_feature()
403 mtu->may_wakeup = !!(index & USB_INTRF_FUNC_SUSPEND_RW); in ep0_handle_feature()
409 if (epnum == 0 || epnum >= mtu->num_eps || in ep0_handle_feature()
414 mep = (is_in ? mtu->in_eps : mtu->out_eps) + epnum; in ep0_handle_feature()
415 if (!mep->desc) in ep0_handle_feature()
420 if (mep->flags & MTU3_EP_WEDGE) in ep0_handle_feature()
436 * negative errno - error happened
437 * zero - need delegate SETUP to gadget driver
438 * positive - already handled
443 void __iomem *mbase = mtu->mac_base; in handle_standard_request()
444 enum usb_device_state state = mtu->g.state; in handle_standard_request()
445 int handled = -EINVAL; in handle_standard_request()
449 value = le16_to_cpu(setup->wValue); in handle_standard_request()
452 switch (setup->bRequest) { in handle_standard_request()
455 mtu->address = (u8) (value & 0x7f); in handle_standard_request()
456 dev_dbg(mtu->dev, "set address to 0x%x\n", mtu->address); in handle_standard_request()
460 dev_conf |= DEV_ADDR(mtu->address); in handle_standard_request()
463 if (mtu->address) in handle_standard_request()
464 usb_gadget_set_state(&mtu->g, USB_STATE_ADDRESS); in handle_standard_request()
466 usb_gadget_set_state(&mtu->g, USB_STATE_DEFAULT); in handle_standard_request()
472 usb_gadget_set_state(&mtu->g, in handle_standard_request()
480 usb_gadget_set_state(&mtu->g, in handle_standard_request()
513 void __iomem *mbase = mtu->mac_base; in ep0_rx_state()
518 dev_dbg(mtu->dev, "%s\n", __func__); in ep0_rx_state()
522 req = &mreq->request; in ep0_rx_state()
526 void *buf = req->buf + req->actual; in ep0_rx_state()
527 unsigned int len = req->length - req->actual; in ep0_rx_state()
532 req->status = -EOVERFLOW; in ep0_rx_state()
535 ep0_read_fifo(mtu->ep0, buf, count); in ep0_rx_state()
536 req->actual += count; in ep0_rx_state()
539 maxp = mtu->g.ep0->maxpacket; in ep0_rx_state()
540 if (count < maxp || req->actual == req->length) { in ep0_rx_state()
541 mtu->ep0_state = MU3D_EP0_STATE_SETUP; in ep0_rx_state()
542 dev_dbg(mtu->dev, "ep0 state: %s\n", in ep0_rx_state()
551 dev_dbg(mtu->dev, "%s: SENDSTALL\n", __func__); in ep0_rx_state()
572 dev_dbg(mtu->dev, "%s\n", __func__); in ep0_tx_state()
577 maxp = mtu->g.ep0->maxpacket; in ep0_tx_state()
578 req = &mreq->request; in ep0_tx_state()
581 src = (u8 *)req->buf + req->actual; in ep0_tx_state()
582 count = min(maxp, req->length - req->actual); in ep0_tx_state()
584 ep0_write_fifo(mtu->ep0, src, count); in ep0_tx_state()
586 dev_dbg(mtu->dev, "%s act=%d, len=%d, cnt=%d, maxp=%d zero=%d\n", in ep0_tx_state()
587 __func__, req->actual, req->length, count, maxp, req->zero); in ep0_tx_state()
589 req->actual += count; in ep0_tx_state()
592 || ((req->actual == req->length) && !req->zero)) in ep0_tx_state()
593 mtu->ep0_state = MU3D_EP0_STATE_TX_END; in ep0_tx_state()
596 csr = mtu3_readl(mtu->mac_base, U3D_EP0CSR) & EP0_W1C_BITS; in ep0_tx_state()
597 mtu3_writel(mtu->mac_base, U3D_EP0CSR, csr | EP0_TXPKTRDY); in ep0_tx_state()
599 dev_dbg(mtu->dev, "%s ep0csr=0x%x\n", __func__, in ep0_tx_state()
600 mtu3_readl(mtu->mac_base, U3D_EP0CSR)); in ep0_tx_state()
609 csr = mtu3_readl(mtu->mac_base, U3D_EP0CSR) & EP0_W1C_BITS; in ep0_read_setup()
610 count = mtu3_readl(mtu->mac_base, U3D_RXCOUNT0); in ep0_read_setup()
612 ep0_read_fifo(mtu->ep0, (u8 *)setup, count); in ep0_read_setup()
614 dev_dbg(mtu->dev, "SETUP req%02x.%02x v%04x i%04x l%04x\n", in ep0_read_setup()
615 setup->bRequestType, setup->bRequest, in ep0_read_setup()
616 le16_to_cpu(setup->wValue), le16_to_cpu(setup->wIndex), in ep0_read_setup()
617 le16_to_cpu(setup->wLength)); in ep0_read_setup()
622 ep0_req_giveback(mtu, &mreq->request); in ep0_read_setup()
624 if (le16_to_cpu(setup->wLength) == 0) { in ep0_read_setup()
626 } else if (setup->bRequestType & USB_DIR_IN) { in ep0_read_setup()
627 mtu3_writel(mtu->mac_base, U3D_EP0CSR, in ep0_read_setup()
629 mtu->ep0_state = MU3D_EP0_STATE_TX; in ep0_read_setup()
631 mtu3_writel(mtu->mac_base, U3D_EP0CSR, in ep0_read_setup()
633 mtu->ep0_state = MU3D_EP0_STATE_RX; in ep0_read_setup()
638 __releases(mtu->lock) in ep0_handle_setup()
639 __acquires(mtu->lock) in ep0_handle_setup()
651 dev_dbg(mtu->dev, "handled %d, ep0_state: %s\n", in ep0_handle_setup()
662 dev_dbg(mtu->dev, "%s stall (%d)\n", __func__, handled); in ep0_handle_setup()
664 ep0_stall_set(mtu->ep0, true, in ep0_handle_setup()
671 if (mtu->test_mode) { in ep0_handle_setup()
679 ep0_req_giveback(mtu, &mreq->request); in ep0_handle_setup()
682 mtu->delayed_status = true; in ep0_handle_setup()
689 if (mreq && !mreq->request.length) in ep0_handle_setup()
690 ep0_req_giveback(mtu, &mreq->request); in ep0_handle_setup()
698 void __iomem *mbase = mtu->mac_base; in mtu3_ep0_isr()
715 mtu->ep0_state = MU3D_EP0_STATE_SETUP; in mtu3_ep0_isr()
719 dev_dbg(mtu->dev, "%s csr=0x%x\n", __func__, csr); in mtu3_ep0_isr()
723 ep0_stall_set(mtu->ep0, false, 0); in mtu3_ep0_isr()
727 dev_dbg(mtu->dev, "ep0_state: %s\n", decode_ep0_state(mtu)); in mtu3_ep0_isr()
728 mtu3_dbg_trace(mtu->dev, "ep0_state %s", decode_ep0_state(mtu)); in mtu3_ep0_isr()
730 switch (mtu->ep0_state) { in mtu3_ep0_isr()
751 ep0_req_giveback(mtu, &mreq->request); in mtu3_ep0_isr()
753 mtu->ep0_state = MU3D_EP0_STATE_SETUP; in mtu3_ep0_isr()
755 dev_dbg(mtu->dev, "ep0_state: %s\n", decode_ep0_state(mtu)); in mtu3_ep0_isr()
763 dev_err(mtu->dev, "SETUP packet len %d != 8 ?\n", len); in mtu3_ep0_isr()
772 ep0_stall_set(mtu->ep0, true, 0); in mtu3_ep0_isr()
785 return -EINVAL; in mtu3_ep0_enable()
791 return -EINVAL; in mtu3_ep0_disable()
796 struct mtu3 *mtu = mep->mtu; in ep0_queue()
798 mreq->mtu = mtu; in ep0_queue()
799 mreq->request.actual = 0; in ep0_queue()
800 mreq->request.status = -EINPROGRESS; in ep0_queue()
802 dev_dbg(mtu->dev, "%s %s (ep0_state: %s), len#%d\n", __func__, in ep0_queue()
803 mep->name, decode_ep0_state(mtu), mreq->request.length); in ep0_queue()
805 switch (mtu->ep0_state) { in ep0_queue()
807 case MU3D_EP0_STATE_RX: /* control-OUT data */ in ep0_queue()
808 case MU3D_EP0_STATE_TX: /* control-IN data */ in ep0_queue()
811 dev_err(mtu->dev, "%s, error in ep0 state %s\n", __func__, in ep0_queue()
813 return -EINVAL; in ep0_queue()
816 if (mtu->delayed_status) { in ep0_queue()
818 mtu->delayed_status = false; in ep0_queue()
824 if (!list_empty(&mep->req_list)) in ep0_queue()
825 return -EBUSY; in ep0_queue()
827 list_add_tail(&mreq->list, &mep->req_list); in ep0_queue()
830 if (mtu->ep0_state == MU3D_EP0_STATE_TX) in ep0_queue()
846 return -EINVAL; in mtu3_ep0_queue()
849 mtu = mep->mtu; in mtu3_ep0_queue()
852 spin_lock_irqsave(&mtu->lock, flags); in mtu3_ep0_queue()
854 spin_unlock_irqrestore(&mtu->lock, flags); in mtu3_ep0_queue()
861 return -EINVAL; in mtu3_ep0_dequeue()
872 return -EINVAL; in mtu3_ep0_halt()
875 mtu = mep->mtu; in mtu3_ep0_halt()
877 dev_dbg(mtu->dev, "%s\n", __func__); in mtu3_ep0_halt()
879 spin_lock_irqsave(&mtu->lock, flags); in mtu3_ep0_halt()
881 if (!list_empty(&mep->req_list)) { in mtu3_ep0_halt()
882 ret = -EBUSY; in mtu3_ep0_halt()
886 switch (mtu->ep0_state) { in mtu3_ep0_halt()
895 ep0_stall_set(mtu->ep0, true, 0); in mtu3_ep0_halt()
898 dev_dbg(mtu->dev, "ep0 can't halt in state %s\n", in mtu3_ep0_halt()
900 ret = -EINVAL; in mtu3_ep0_halt()
904 spin_unlock_irqrestore(&mtu->lock, flags); in mtu3_ep0_halt()
910 .disable = mtu3_ep0_disable,