// SPDX-License-Identifier: GPL-2.0+
/*
 * aspeed-vhub -- Driver for Aspeed SoC "vHub" USB gadget
 *
 * ep0.c - Endpoint 0 handling
 *
 * Copyright 2017 IBM Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/list.h>
#include <linux/interrupt.h>
#include <linux/proc_fs.h>
#include <linux/prefetch.h>
#include <linux/clk.h>
#include <linux/usb/gadget.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/regmap.h>
#include <linux/dma-mapping.h>

#include "vhub.h"

int ast_vhub_reply(struct ast_vhub_ep *ep, char *ptr, int len)
{
	struct usb_request *req = &ep->ep0.req.req;
	int rc;

	if (WARN_ON(ep->d_idx != 0))
		return std_req_stall;
	if (WARN_ON(!ep->ep0.dir_in))
		return std_req_stall;
	if (WARN_ON(len > AST_VHUB_EP0_MAX_PACKET))
		return std_req_stall;
	if (WARN_ON(req->status == -EINPROGRESS))
		return std_req_stall;

	req->buf = ptr;
	req->length = len;
	req->complete = NULL;
	req->zero = true;

	/*
	 * Call internal queue directly after dropping the lock. This is
	 * safe to do as the reply is always the last thing done when
	 * processing a SETUP packet, usually as a tail call
	 */
	spin_unlock(&ep->vhub->lock);
	if (ep->ep.ops->queue(&ep->ep, req, GFP_ATOMIC))
		rc = std_req_stall;
	else
		rc = std_req_data;
	spin_lock(&ep->vhub->lock);
	return rc;
}

int __ast_vhub_simple_reply(struct ast_vhub_ep *ep, int len, ...)
{
	u8 *buffer = ep->buf;
	unsigned int i;
	va_list args;

	va_start(args, len);

	/* Copy data directly into EP buffer */
	for (i = 0; i < len; i++)
		buffer[i] = va_arg(args, int);
	va_end(args);

	/* req->buf NULL means data is already there */
	return ast_vhub_reply(ep, NULL, len);
}

void ast_vhub_ep0_handle_setup(struct ast_vhub_ep *ep)
{
	struct usb_ctrlrequest crq;
	enum std_req_rc std_req_rc;
	int rc = -ENODEV;

	if (WARN_ON(ep->d_idx != 0))
		return;

	/*
	 * Grab the setup packet from the chip and byteswap
	 * interesting fields
	 */
	memcpy_fromio(&crq, ep->ep0.setup, sizeof(crq));

	EPDBG(ep, "SETUP packet %02x/%02x/%04x/%04x/%04x [%s] st=%d\n",
	      crq.bRequestType, crq.bRequest,
	       le16_to_cpu(crq.wValue),
	       le16_to_cpu(crq.wIndex),
	       le16_to_cpu(crq.wLength),
	       (crq.bRequestType & USB_DIR_IN) ? "in" : "out",
	       ep->ep0.state);

	/*
	 * Check our state, cancel pending requests if needed
	 *
	 * Note: Under some circumstances, we can get a new setup
	 * packet while waiting for the stall ack, just accept it.
	 *
	 * In any case, a SETUP packet in wrong state should have
	 * reset the HW state machine, so let's just log, nuke
	 * requests, move on.
	 */
	if (ep->ep0.state != ep0_state_token &&
	    ep->ep0.state != ep0_state_stall) {
		EPDBG(ep, "wrong state\n");
		ast_vhub_nuke(ep, -EIO);
	}

	/* Calculate next state for EP0 */
	ep->ep0.state = ep0_state_data;
	ep->ep0.dir_in = !!(crq.bRequestType & USB_DIR_IN);

	/* If this is the vHub, we handle requests differently */
	std_req_rc = std_req_driver;
	if (ep->dev == NULL) {
		if ((crq.bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD)
			std_req_rc = ast_vhub_std_hub_request(ep, &crq);
		else if ((crq.bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS)
			std_req_rc = ast_vhub_class_hub_request(ep, &crq);
		else
			std_req_rc = std_req_stall;
	} else if ((crq.bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD)
		std_req_rc = ast_vhub_std_dev_request(ep, &crq);

	/* Act upon result */
	switch(std_req_rc) {
	case std_req_complete:
		goto complete;
	case std_req_stall:
		goto stall;
	case std_req_driver:
		break;
	case std_req_data:
		return;
	}

	/* Pass request up to the gadget driver */
	if (WARN_ON(!ep->dev))
		goto stall;
	if (ep->dev->driver) {
		EPDBG(ep, "forwarding to gadget...\n");
		spin_unlock(&ep->vhub->lock);
		rc = ep->dev->driver->setup(&ep->dev->gadget, &crq);
		spin_lock(&ep->vhub->lock);
		EPDBG(ep, "driver returned %d\n", rc);
	} else {
		EPDBG(ep, "no gadget for request !\n");
	}
	if (rc >= 0)
		return;

 stall:
	EPDBG(ep, "stalling\n");
	writel(VHUB_EP0_CTRL_STALL, ep->ep0.ctlstat);
	ep->ep0.state = ep0_state_stall;
	ep->ep0.dir_in = false;
	return;

 complete:
	EPVDBG(ep, "sending [in] status with no data\n");
	writel(VHUB_EP0_TX_BUFF_RDY, ep->ep0.ctlstat);
	ep->ep0.state = ep0_state_status;
	ep->ep0.dir_in = false;
}


static void ast_vhub_ep0_do_send(struct ast_vhub_ep *ep,
				 struct ast_vhub_req *req)
{
	unsigned int chunk;
	u32 reg;

	/* If this is a 0-length request, it's the gadget trying to
	 * send a status on our behalf. We take it from here.
	 */
	if (req->req.length == 0)
		req->last_desc = 1;

	/* Are we done ? Complete request, otherwise wait for next interrupt */
	if (req->last_desc >= 0) {
		EPVDBG(ep, "complete send %d/%d\n",
		       req->req.actual, req->req.length);
		ep->ep0.state = ep0_state_status;
		writel(VHUB_EP0_RX_BUFF_RDY, ep->ep0.ctlstat);
		ast_vhub_done(ep, req, 0);
		return;
	}

	/*
	 * Next chunk cropped to max packet size. Also check if this
	 * is the last packet
	 */
	chunk = req->req.length - req->req.actual;
	if (chunk > ep->ep.maxpacket)
		chunk = ep->ep.maxpacket;
	else if ((chunk < ep->ep.maxpacket) || !req->req.zero)
		req->last_desc = 1;

	EPVDBG(ep, "send chunk=%d last=%d, req->act=%d mp=%d\n",
	       chunk, req->last_desc, req->req.actual, ep->ep.maxpacket);

	/*
	 * Copy data if any (internal requests already have data
	 * in the EP buffer)
	 */
	if (chunk && req->req.buf)
		memcpy(ep->buf, req->req.buf + req->req.actual, chunk);

	vhub_dma_workaround(ep->buf);

	/* Remember chunk size and trigger send */
	reg = VHUB_EP0_SET_TX_LEN(chunk);
	writel(reg, ep->ep0.ctlstat);
	writel(reg | VHUB_EP0_TX_BUFF_RDY, ep->ep0.ctlstat);
	req->req.actual += chunk;
}

static void ast_vhub_ep0_rx_prime(struct ast_vhub_ep *ep)
{
	EPVDBG(ep, "rx prime\n");

	/* Prime endpoint for receiving data */
	writel(VHUB_EP0_RX_BUFF_RDY, ep->ep0.ctlstat);
}

static void ast_vhub_ep0_do_receive(struct ast_vhub_ep *ep, struct ast_vhub_req *req,
				    unsigned int len)
{
	unsigned int remain;
	int rc = 0;

	/* We are receiving... grab request */
	remain = req->req.length - req->req.actual;

	EPVDBG(ep, "receive got=%d remain=%d\n", len, remain);

	/* Are we getting more than asked ? */
	if (len > remain) {
		EPDBG(ep, "receiving too much (ovf: %d) !\n",
		      len - remain);
		len = remain;
		rc = -EOVERFLOW;
	}
	if (len && req->req.buf)
		memcpy(req->req.buf + req->req.actual, ep->buf, len);
	req->req.actual += len;

	/* Done ? */
	if (len < ep->ep.maxpacket || len == remain) {
		ep->ep0.state = ep0_state_status;
		writel(VHUB_EP0_TX_BUFF_RDY, ep->ep0.ctlstat);
		ast_vhub_done(ep, req, rc);
	} else
		ast_vhub_ep0_rx_prime(ep);
}

void ast_vhub_ep0_handle_ack(struct ast_vhub_ep *ep, bool in_ack)
{
	struct ast_vhub_req *req;
	struct ast_vhub *vhub = ep->vhub;
	struct device *dev = &vhub->pdev->dev;
	bool stall = false;
	u32 stat;

	/* Read EP0 status */
	stat = readl(ep->ep0.ctlstat);

	/* Grab current request if any */
	req = list_first_entry_or_null(&ep->queue, struct ast_vhub_req, queue);

	EPVDBG(ep, "ACK status=%08x,state=%d is_in=%d in_ack=%d req=%p\n",
		stat, ep->ep0.state, ep->ep0.dir_in, in_ack, req);

	switch(ep->ep0.state) {
	case ep0_state_token:
		/* There should be no request queued in that state... */
		if (req) {
			dev_warn(dev, "request present while in TOKEN state\n");
			ast_vhub_nuke(ep, -EINVAL);
		}
		dev_warn(dev, "ack while in TOKEN state\n");
		stall = true;
		break;
	case ep0_state_data:
		/* Check the state bits corresponding to our direction */
		if ((ep->ep0.dir_in && (stat & VHUB_EP0_TX_BUFF_RDY)) ||
		    (!ep->ep0.dir_in && (stat & VHUB_EP0_RX_BUFF_RDY)) ||
		    (ep->ep0.dir_in != in_ack)) {
			/* In that case, ignore interrupt */
			dev_warn(dev, "irq state mismatch");
			break;
		}
		/*
		 * We are in data phase and there's no request, something is
		 * wrong, stall
		 */
		if (!req) {
			dev_warn(dev, "data phase, no request\n");
			stall = true;
			break;
		}

		/* We have a request, handle data transfers */
		if (ep->ep0.dir_in)
			ast_vhub_ep0_do_send(ep, req);
		else
			ast_vhub_ep0_do_receive(ep, req, VHUB_EP0_RX_LEN(stat));
		return;
	case ep0_state_status:
		/* Nuke stale requests */
		if (req) {
			dev_warn(dev, "request present while in STATUS state\n");
			ast_vhub_nuke(ep, -EINVAL);
		}

		/*
		 * If the status phase completes with the wrong ack, stall
		 * the endpoint just in case, to abort whatever the host
		 * was doing.
		 */
		if (ep->ep0.dir_in == in_ack) {
			dev_warn(dev, "status direction mismatch\n");
			stall = true;
		}
		break;
	case ep0_state_stall:
		/*
		 * There shouldn't be any request left, but nuke just in case
		 * otherwise the stale request will block subsequent ones
		 */
		ast_vhub_nuke(ep, -EIO);
		break;
	}

	/* Reset to token state or stall */
	if (stall) {
		writel(VHUB_EP0_CTRL_STALL, ep->ep0.ctlstat);
		ep->ep0.state = ep0_state_stall;
	} else
		ep->ep0.state = ep0_state_token;
}

static int ast_vhub_ep0_queue(struct usb_ep* u_ep, struct usb_request *u_req,
			      gfp_t gfp_flags)
{
	struct ast_vhub_req *req = to_ast_req(u_req);
	struct ast_vhub_ep *ep = to_ast_ep(u_ep);
	struct ast_vhub *vhub = ep->vhub;
	struct device *dev = &vhub->pdev->dev;
	unsigned long flags;

	/* Paranoid cheks */
	if (!u_req || (!u_req->complete && !req->internal)) {
		dev_warn(dev, "Bogus EP0 request ! u_req=%p\n", u_req);
		if (u_req) {
			dev_warn(dev, "complete=%p internal=%d\n",
				 u_req->complete, req->internal);
		}
		return -EINVAL;
	}

	/* Not endpoint 0 ? */
	if (WARN_ON(ep->d_idx != 0))
		return -EINVAL;

	/* Disabled device */
	if (ep->dev && !ep->dev->enabled)
		return -ESHUTDOWN;

	/* Data, no buffer and not internal ? */
	if (u_req->length && !u_req->buf && !req->internal) {
		dev_warn(dev, "Request with no buffer !\n");
		return -EINVAL;
	}

	EPVDBG(ep, "enqueue req @%p\n", req);
	EPVDBG(ep, "  l=%d zero=%d noshort=%d is_in=%d\n",
	       u_req->length, u_req->zero,
	       u_req->short_not_ok, ep->ep0.dir_in);

	/* Initialize request progress fields */
	u_req->status = -EINPROGRESS;
	u_req->actual = 0;
	req->last_desc = -1;
	req->active = false;

	spin_lock_irqsave(&vhub->lock, flags);

	/* EP0 can only support a single request at a time */
	if (!list_empty(&ep->queue) ||
	    ep->ep0.state == ep0_state_token ||
	    ep->ep0.state == ep0_state_stall) {
		dev_warn(dev, "EP0: Request in wrong state\n");
	        EPVDBG(ep, "EP0: list_empty=%d state=%d\n",
		       list_empty(&ep->queue), ep->ep0.state);
		spin_unlock_irqrestore(&vhub->lock, flags);
		return -EBUSY;
	}

	/* Add request to list and kick processing if empty */
	list_add_tail(&req->queue, &ep->queue);

	if (ep->ep0.dir_in) {
		/* IN request, send data */
		ast_vhub_ep0_do_send(ep, req);
	} else if (u_req->length == 0) {
		/* 0-len request, send completion as rx */
		EPVDBG(ep, "0-length rx completion\n");
		ep->ep0.state = ep0_state_status;
		writel(VHUB_EP0_TX_BUFF_RDY, ep->ep0.ctlstat);
		ast_vhub_done(ep, req, 0);
	} else {
		/* OUT request, start receiver */
		ast_vhub_ep0_rx_prime(ep);
	}

	spin_unlock_irqrestore(&vhub->lock, flags);

	return 0;
}

static int ast_vhub_ep0_dequeue(struct usb_ep* u_ep, struct usb_request *u_req)
{
	struct ast_vhub_ep *ep = to_ast_ep(u_ep);
	struct ast_vhub *vhub = ep->vhub;
	struct ast_vhub_req *req;
	unsigned long flags;
	int rc = -EINVAL;

	spin_lock_irqsave(&vhub->lock, flags);

	/* Only one request can be in the queue */
	req = list_first_entry_or_null(&ep->queue, struct ast_vhub_req, queue);

	/* Is it ours ? */
	if (req && u_req == &req->req) {
		EPVDBG(ep, "dequeue req @%p\n", req);

		/*
		 * We don't have to deal with "active" as all
		 * DMAs go to the EP buffers, not the request.
		 */
		ast_vhub_done(ep, req, -ECONNRESET);

		/* We do stall the EP to clean things up in HW */
		writel(VHUB_EP0_CTRL_STALL, ep->ep0.ctlstat);
		ep->ep0.state = ep0_state_status;
		ep->ep0.dir_in = false;
		rc = 0;
	}
	spin_unlock_irqrestore(&vhub->lock, flags);
	return rc;
}


static const struct usb_ep_ops ast_vhub_ep0_ops = {
	.queue		= ast_vhub_ep0_queue,
	.dequeue	= ast_vhub_ep0_dequeue,
	.alloc_request	= ast_vhub_alloc_request,
	.free_request	= ast_vhub_free_request,
};

void ast_vhub_reset_ep0(struct ast_vhub_dev *dev)
{
	struct ast_vhub_ep *ep = &dev->ep0;

	ast_vhub_nuke(ep, -EIO);
	ep->ep0.state = ep0_state_token;
}


void ast_vhub_init_ep0(struct ast_vhub *vhub, struct ast_vhub_ep *ep,
		       struct ast_vhub_dev *dev)
{
	memset(ep, 0, sizeof(*ep));

	INIT_LIST_HEAD(&ep->ep.ep_list);
	INIT_LIST_HEAD(&ep->queue);
	ep->ep.ops = &ast_vhub_ep0_ops;
	ep->ep.name = "ep0";
	ep->ep.caps.type_control = true;
	usb_ep_set_maxpacket_limit(&ep->ep, AST_VHUB_EP0_MAX_PACKET);
	ep->d_idx = 0;
	ep->dev = dev;
	ep->vhub = vhub;
	ep->ep0.state = ep0_state_token;
	INIT_LIST_HEAD(&ep->ep0.req.queue);
	ep->ep0.req.internal = true;

	/* Small difference between vHub and devices */
	if (dev) {
		ep->ep0.ctlstat = dev->regs + AST_VHUB_DEV_EP0_CTRL;
		ep->ep0.setup = vhub->regs +
			AST_VHUB_SETUP0 + 8 * (dev->index + 1);
		ep->buf = vhub->ep0_bufs +
			AST_VHUB_EP0_MAX_PACKET * (dev->index + 1);
		ep->buf_dma = vhub->ep0_bufs_dma +
			AST_VHUB_EP0_MAX_PACKET * (dev->index + 1);
	} else {
		ep->ep0.ctlstat = vhub->regs + AST_VHUB_EP0_CTRL;
		ep->ep0.setup = vhub->regs + AST_VHUB_SETUP0;
		ep->buf = vhub->ep0_bufs;
		ep->buf_dma = vhub->ep0_bufs_dma;
	}
}
