// 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 */
	if (ep->ep0.state != ep0_state_token) {
		EPDBG(ep, "wrong state\n");
		ast_vhub_nuke(ep, -EIO);

		/*
		 * Accept the packet regardless, this seems to happen
		 * when stalling a SETUP packet that has an OUT data
		 * phase.
		 */
		ast_vhub_nuke(ep, 0);
		goto stall;
	}

	/* 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_status;
	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)) {
			dev_warn(dev, "irq state mismatch");
			stall = true;
			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;
		}
	}

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

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 || ep->dev->suspended))
		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) {
		dev_warn(dev, "EP0: Request in wrong state\n");
		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_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;
	}
}
