/*
 * Marvell NFC-over-USB driver: USB interface related functions
 *
 * Copyright (C) 2014, Marvell International Ltd.
 *
 * This software file (the "File") is distributed by Marvell International
 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
 * (the "License").  You may use, redistribute and/or modify this File in
 * accordance with the terms and conditions of the License, a copy of which
 * is available on the worldwide web at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
 *
 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
 * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
 * this warranty disclaimer.
 **/

#include <linux/module.h>
#include <linux/usb.h>
#include <linux/nfc.h>
#include <net/nfc/nci.h>
#include <net/nfc/nci_core.h>
#include "nfcmrvl.h"

static struct usb_device_id nfcmrvl_table[] = {
	{ USB_DEVICE_AND_INTERFACE_INFO(0x1286, 0x2046,
					USB_CLASS_VENDOR_SPEC, 4, 1) },
	{ }	/* Terminating entry */
};

MODULE_DEVICE_TABLE(usb, nfcmrvl_table);

#define NFCMRVL_USB_BULK_RUNNING	1
#define NFCMRVL_USB_SUSPENDING		2

struct nfcmrvl_usb_drv_data {
	struct usb_device *udev;
	struct usb_interface *intf;
	unsigned long flags;
	struct work_struct waker;
	struct usb_anchor tx_anchor;
	struct usb_anchor bulk_anchor;
	struct usb_anchor deferred;
	int tx_in_flight;
	/* protects tx_in_flight */
	spinlock_t txlock;
	struct usb_endpoint_descriptor *bulk_tx_ep;
	struct usb_endpoint_descriptor *bulk_rx_ep;
	int suspend_count;
	struct nfcmrvl_private *priv;
};

static int nfcmrvl_inc_tx(struct nfcmrvl_usb_drv_data *drv_data)
{
	unsigned long flags;
	int rv;

	spin_lock_irqsave(&drv_data->txlock, flags);
	rv = test_bit(NFCMRVL_USB_SUSPENDING, &drv_data->flags);
	if (!rv)
		drv_data->tx_in_flight++;
	spin_unlock_irqrestore(&drv_data->txlock, flags);

	return rv;
}

static void nfcmrvl_bulk_complete(struct urb *urb)
{
	struct nfcmrvl_usb_drv_data *drv_data = urb->context;
	struct sk_buff *skb;
	int err;

	dev_dbg(&drv_data->udev->dev, "urb %p status %d count %d\n",
		urb, urb->status, urb->actual_length);

	if (!test_bit(NFCMRVL_NCI_RUNNING, &drv_data->flags))
		return;

	if (!urb->status) {
		skb = nci_skb_alloc(drv_data->priv->ndev, urb->actual_length,
				    GFP_ATOMIC);
		if (!skb) {
			nfc_err(&drv_data->udev->dev, "failed to alloc mem\n");
		} else {
			skb_put_data(skb, urb->transfer_buffer,
				     urb->actual_length);
			if (nfcmrvl_nci_recv_frame(drv_data->priv, skb) < 0)
				nfc_err(&drv_data->udev->dev,
					"corrupted Rx packet\n");
		}
	}

	if (!test_bit(NFCMRVL_USB_BULK_RUNNING, &drv_data->flags))
		return;

	usb_anchor_urb(urb, &drv_data->bulk_anchor);
	usb_mark_last_busy(drv_data->udev);

	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (err) {
		/* -EPERM: urb is being killed;
		 * -ENODEV: device got disconnected
		 */
		if (err != -EPERM && err != -ENODEV)
			nfc_err(&drv_data->udev->dev,
				"urb %p failed to resubmit (%d)\n", urb, -err);
		usb_unanchor_urb(urb);
	}
}

static int
nfcmrvl_submit_bulk_urb(struct nfcmrvl_usb_drv_data *drv_data, gfp_t mem_flags)
{
	struct urb *urb;
	unsigned char *buf;
	unsigned int pipe;
	int err, size = NFCMRVL_NCI_MAX_EVENT_SIZE;

	if (!drv_data->bulk_rx_ep)
		return -ENODEV;

	urb = usb_alloc_urb(0, mem_flags);
	if (!urb)
		return -ENOMEM;

	buf = kmalloc(size, mem_flags);
	if (!buf) {
		usb_free_urb(urb);
		return -ENOMEM;
	}

	pipe = usb_rcvbulkpipe(drv_data->udev,
			       drv_data->bulk_rx_ep->bEndpointAddress);

	usb_fill_bulk_urb(urb, drv_data->udev, pipe, buf, size,
			  nfcmrvl_bulk_complete, drv_data);

	urb->transfer_flags |= URB_FREE_BUFFER;

	usb_mark_last_busy(drv_data->udev);
	usb_anchor_urb(urb, &drv_data->bulk_anchor);

	err = usb_submit_urb(urb, mem_flags);
	if (err) {
		if (err != -EPERM && err != -ENODEV)
			nfc_err(&drv_data->udev->dev,
				"urb %p submission failed (%d)\n", urb, -err);
		usb_unanchor_urb(urb);
	}

	usb_free_urb(urb);

	return err;
}

static void nfcmrvl_tx_complete(struct urb *urb)
{
	struct sk_buff *skb = urb->context;
	struct nci_dev *ndev = (struct nci_dev *)skb->dev;
	struct nfcmrvl_private *priv = nci_get_drvdata(ndev);
	struct nfcmrvl_usb_drv_data *drv_data = priv->drv_data;
	unsigned long flags;

	nfc_info(priv->dev, "urb %p status %d count %d\n",
		 urb, urb->status, urb->actual_length);

	spin_lock_irqsave(&drv_data->txlock, flags);
	drv_data->tx_in_flight--;
	spin_unlock_irqrestore(&drv_data->txlock, flags);

	kfree(urb->setup_packet);
	kfree_skb(skb);
}

static int nfcmrvl_usb_nci_open(struct nfcmrvl_private *priv)
{
	struct nfcmrvl_usb_drv_data *drv_data = priv->drv_data;
	int err;

	err = usb_autopm_get_interface(drv_data->intf);
	if (err)
		return err;

	drv_data->intf->needs_remote_wakeup = 1;

	err = nfcmrvl_submit_bulk_urb(drv_data, GFP_KERNEL);
	if (err)
		goto failed;

	set_bit(NFCMRVL_USB_BULK_RUNNING, &drv_data->flags);
	nfcmrvl_submit_bulk_urb(drv_data, GFP_KERNEL);

	usb_autopm_put_interface(drv_data->intf);
	return 0;

failed:
	usb_autopm_put_interface(drv_data->intf);
	return err;
}

static void nfcmrvl_usb_stop_traffic(struct nfcmrvl_usb_drv_data *drv_data)
{
	usb_kill_anchored_urbs(&drv_data->bulk_anchor);
}

static int nfcmrvl_usb_nci_close(struct nfcmrvl_private *priv)
{
	struct nfcmrvl_usb_drv_data *drv_data = priv->drv_data;
	int err;

	cancel_work_sync(&drv_data->waker);

	clear_bit(NFCMRVL_USB_BULK_RUNNING, &drv_data->flags);

	nfcmrvl_usb_stop_traffic(drv_data);
	usb_kill_anchored_urbs(&drv_data->tx_anchor);
	err = usb_autopm_get_interface(drv_data->intf);
	if (err)
		goto failed;

	drv_data->intf->needs_remote_wakeup = 0;
	usb_autopm_put_interface(drv_data->intf);

failed:
	usb_scuttle_anchored_urbs(&drv_data->deferred);
	return 0;
}

static int nfcmrvl_usb_nci_send(struct nfcmrvl_private *priv,
				struct sk_buff *skb)
{
	struct nfcmrvl_usb_drv_data *drv_data = priv->drv_data;
	struct urb *urb;
	unsigned int pipe;
	int err;

	if (!drv_data->bulk_tx_ep)
		return -ENODEV;

	urb = usb_alloc_urb(0, GFP_ATOMIC);
	if (!urb)
		return -ENOMEM;

	pipe = usb_sndbulkpipe(drv_data->udev,
				drv_data->bulk_tx_ep->bEndpointAddress);

	usb_fill_bulk_urb(urb, drv_data->udev, pipe, skb->data, skb->len,
			  nfcmrvl_tx_complete, skb);

	err = nfcmrvl_inc_tx(drv_data);
	if (err) {
		usb_anchor_urb(urb, &drv_data->deferred);
		schedule_work(&drv_data->waker);
		err = 0;
		goto done;
	}

	usb_anchor_urb(urb, &drv_data->tx_anchor);

	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (err) {
		if (err != -EPERM && err != -ENODEV)
			nfc_err(&drv_data->udev->dev,
				"urb %p submission failed (%d)\n", urb, -err);
		kfree(urb->setup_packet);
		usb_unanchor_urb(urb);
	} else {
		usb_mark_last_busy(drv_data->udev);
	}

done:
	usb_free_urb(urb);
	return err;
}

static struct nfcmrvl_if_ops usb_ops = {
	.nci_open = nfcmrvl_usb_nci_open,
	.nci_close = nfcmrvl_usb_nci_close,
	.nci_send = nfcmrvl_usb_nci_send,
};

static void nfcmrvl_waker(struct work_struct *work)
{
	struct nfcmrvl_usb_drv_data *drv_data =
			container_of(work, struct nfcmrvl_usb_drv_data, waker);
	int err;

	err = usb_autopm_get_interface(drv_data->intf);
	if (err)
		return;

	usb_autopm_put_interface(drv_data->intf);
}

static int nfcmrvl_probe(struct usb_interface *intf,
			 const struct usb_device_id *id)
{
	struct usb_endpoint_descriptor *ep_desc;
	struct nfcmrvl_usb_drv_data *drv_data;
	struct nfcmrvl_private *priv;
	int i;
	struct usb_device *udev = interface_to_usbdev(intf);
	struct nfcmrvl_platform_data config;

	/* No configuration for USB */
	memset(&config, 0, sizeof(config));
	config.reset_n_io = -EINVAL;

	nfc_info(&udev->dev, "intf %p id %p\n", intf, id);

	drv_data = devm_kzalloc(&intf->dev, sizeof(*drv_data), GFP_KERNEL);
	if (!drv_data)
		return -ENOMEM;

	for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
		ep_desc = &intf->cur_altsetting->endpoint[i].desc;

		if (!drv_data->bulk_tx_ep &&
		    usb_endpoint_is_bulk_out(ep_desc)) {
			drv_data->bulk_tx_ep = ep_desc;
			continue;
		}

		if (!drv_data->bulk_rx_ep &&
		    usb_endpoint_is_bulk_in(ep_desc)) {
			drv_data->bulk_rx_ep = ep_desc;
			continue;
		}
	}

	if (!drv_data->bulk_tx_ep || !drv_data->bulk_rx_ep)
		return -ENODEV;

	drv_data->udev = udev;
	drv_data->intf = intf;

	INIT_WORK(&drv_data->waker, nfcmrvl_waker);
	spin_lock_init(&drv_data->txlock);

	init_usb_anchor(&drv_data->tx_anchor);
	init_usb_anchor(&drv_data->bulk_anchor);
	init_usb_anchor(&drv_data->deferred);

	priv = nfcmrvl_nci_register_dev(NFCMRVL_PHY_USB, drv_data, &usb_ops,
					&intf->dev, &config);
	if (IS_ERR(priv))
		return PTR_ERR(priv);

	drv_data->priv = priv;
	drv_data->priv->support_fw_dnld = false;

	usb_set_intfdata(intf, drv_data);

	return 0;
}

static void nfcmrvl_disconnect(struct usb_interface *intf)
{
	struct nfcmrvl_usb_drv_data *drv_data = usb_get_intfdata(intf);

	if (!drv_data)
		return;

	nfc_info(&drv_data->udev->dev, "intf %p\n", intf);

	nfcmrvl_nci_unregister_dev(drv_data->priv);

	usb_set_intfdata(drv_data->intf, NULL);
}

#ifdef CONFIG_PM
static int nfcmrvl_suspend(struct usb_interface *intf, pm_message_t message)
{
	struct nfcmrvl_usb_drv_data *drv_data = usb_get_intfdata(intf);

	nfc_info(&drv_data->udev->dev, "intf %p\n", intf);

	if (drv_data->suspend_count++)
		return 0;

	spin_lock_irq(&drv_data->txlock);
	if (!(PMSG_IS_AUTO(message) && drv_data->tx_in_flight)) {
		set_bit(NFCMRVL_USB_SUSPENDING, &drv_data->flags);
		spin_unlock_irq(&drv_data->txlock);
	} else {
		spin_unlock_irq(&drv_data->txlock);
		drv_data->suspend_count--;
		return -EBUSY;
	}

	nfcmrvl_usb_stop_traffic(drv_data);
	usb_kill_anchored_urbs(&drv_data->tx_anchor);

	return 0;
}

static void nfcmrvl_play_deferred(struct nfcmrvl_usb_drv_data *drv_data)
{
	struct urb *urb;
	int err;

	while ((urb = usb_get_from_anchor(&drv_data->deferred))) {
		err = usb_submit_urb(urb, GFP_ATOMIC);
		if (err)
			break;

		drv_data->tx_in_flight++;
	}
	usb_scuttle_anchored_urbs(&drv_data->deferred);
}

static int nfcmrvl_resume(struct usb_interface *intf)
{
	struct nfcmrvl_usb_drv_data *drv_data = usb_get_intfdata(intf);
	int err = 0;

	nfc_info(&drv_data->udev->dev, "intf %p\n", intf);

	if (--drv_data->suspend_count)
		return 0;

	if (!test_bit(NFCMRVL_NCI_RUNNING, &drv_data->flags))
		goto done;

	if (test_bit(NFCMRVL_USB_BULK_RUNNING, &drv_data->flags)) {
		err = nfcmrvl_submit_bulk_urb(drv_data, GFP_NOIO);
		if (err) {
			clear_bit(NFCMRVL_USB_BULK_RUNNING, &drv_data->flags);
			goto failed;
		}

		nfcmrvl_submit_bulk_urb(drv_data, GFP_NOIO);
	}

	spin_lock_irq(&drv_data->txlock);
	nfcmrvl_play_deferred(drv_data);
	clear_bit(NFCMRVL_USB_SUSPENDING, &drv_data->flags);
	spin_unlock_irq(&drv_data->txlock);

	return 0;

failed:
	usb_scuttle_anchored_urbs(&drv_data->deferred);
done:
	spin_lock_irq(&drv_data->txlock);
	clear_bit(NFCMRVL_USB_SUSPENDING, &drv_data->flags);
	spin_unlock_irq(&drv_data->txlock);

	return err;
}
#endif

static struct usb_driver nfcmrvl_usb_driver = {
	.name		= "nfcmrvl",
	.probe		= nfcmrvl_probe,
	.disconnect	= nfcmrvl_disconnect,
#ifdef CONFIG_PM
	.suspend	= nfcmrvl_suspend,
	.resume		= nfcmrvl_resume,
	.reset_resume	= nfcmrvl_resume,
#endif
	.id_table	= nfcmrvl_table,
	.supports_autosuspend = 1,
	.disable_hub_initiated_lpm = 1,
	.soft_unbind = 1,
};
module_usb_driver(nfcmrvl_usb_driver);

MODULE_AUTHOR("Marvell International Ltd.");
MODULE_DESCRIPTION("Marvell NFC-over-USB driver");
MODULE_LICENSE("GPL v2");
