/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/completion.h>
#include <linux/debugfs.h>
#include <linux/export.h>
#include <linux/fs.h>
#include <linux/if_ether.h>
#include <linux/ioctl.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/msm_ipa.h>
#include <linux/mutex.h>
#include <linux/skbuff.h>
#include <linux/types.h>
#include <linux/ipa.h>
#include <linux/netdevice.h>
#include "ipa_i.h"

#define TETH_BRIDGE_DRV_NAME "ipa_tethering_bridge"

#define TETH_DBG(fmt, args...) \
	pr_debug(TETH_BRIDGE_DRV_NAME " %s:%d " fmt, \
		 __func__, __LINE__, ## args)
#define TETH_DBG_FUNC_ENTRY() \
	pr_debug(TETH_BRIDGE_DRV_NAME " %s:%d ENTRY\n", __func__, __LINE__)
#define TETH_DBG_FUNC_EXIT() \
	pr_debug(TETH_BRIDGE_DRV_NAME " %s:%d EXIT\n", __func__, __LINE__)
#define TETH_ERR(fmt, args...) \
	pr_err(TETH_BRIDGE_DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args)

/**
 * struct ipa3_teth_bridge_ctx - Tethering bridge driver context information
 * @class: kernel class pointer
 * @dev_num: kernel device number
 * @dev: kernel device struct pointer
 * @cdev: kernel character device struct
 */
struct ipa3_teth_bridge_ctx {
	struct class *class;
	dev_t dev_num;
	struct device *dev;
	struct cdev cdev;
};
static struct ipa3_teth_bridge_ctx *ipa3_teth_ctx;

/**
* teth_bridge_ipa_cb() - Callback to handle IPA data path events
* @priv - private data
* @evt - event type
* @data - event specific data (usually skb)
*
* This callback is called by IPA driver for exception packets from USB.
* All exception packets are handled by Q6 and should not reach this function.
* Packets will arrive to AP exception pipe only in case where packets are
* sent from USB before Q6 has setup the call.
*/
static void teth_bridge_ipa_cb(void *priv, enum ipa_dp_evt_type evt,
	unsigned long data)
{
	struct sk_buff *skb = (struct sk_buff *)data;

	TETH_DBG_FUNC_ENTRY();
	if (evt != IPA_RECEIVE) {
		TETH_ERR("unexpected event %d\n", evt);
		WARN_ON(1);
		return;
	}

	TETH_ERR("Unexpected exception packet from USB, dropping packet\n");
	dev_kfree_skb_any(skb);
	TETH_DBG_FUNC_EXIT();
}

/**
* ipa3_teth_bridge_init() - Initialize the Tethering bridge driver
* @params - in/out params for USB initialization API (please look at struct
*  definition for more info)
*
* USB driver gets a pointer to a callback function (usb_notify_cb) and an
* associated data.
*
* Builds IPA resource manager dependency graph.
*
* Return codes: 0: success,
*		-EINVAL - Bad parameter
*		Other negative value - Failure
*/
int ipa3_teth_bridge_init(struct teth_bridge_init_params *params)
{
	TETH_DBG_FUNC_ENTRY();

	if (!params) {
		TETH_ERR("Bad parameter\n");
		TETH_DBG_FUNC_EXIT();
		return -EINVAL;
	}

	params->usb_notify_cb = teth_bridge_ipa_cb;
	params->private_data = NULL;
	params->skip_ep_cfg = true;

	TETH_DBG_FUNC_EXIT();
	return 0;
}

/**
* ipa3_teth_bridge_disconnect() - Disconnect tethering bridge module
*/
int ipa3_teth_bridge_disconnect(enum ipa_client_type client)
{
	TETH_DBG_FUNC_ENTRY();
	ipa_rm_delete_dependency(IPA_RM_RESOURCE_USB_PROD,
				 IPA_RM_RESOURCE_Q6_CONS);
	ipa_rm_delete_dependency(IPA_RM_RESOURCE_Q6_PROD,
				 IPA_RM_RESOURCE_USB_CONS);
	TETH_DBG_FUNC_EXIT();

	return 0;
}

/**
* ipa3_teth_bridge_connect() - Connect bridge for a tethered Rmnet / MBIM call
* @connect_params:	Connection info
*
* Return codes: 0: success
*		-EINVAL: invalid parameters
*		-EPERM: Operation not permitted as the bridge is already
*		connected
*/
int ipa3_teth_bridge_connect(struct teth_bridge_connect_params *connect_params)
{
	int res = 0;

	TETH_DBG_FUNC_ENTRY();

	/* Build the dependency graph, first add_dependency call is sync
	 * in order to make sure the IPA clocks are up before we continue
	 * and notify the USB driver it may continue.
	 */
	res = ipa_rm_add_dependency_sync(IPA_RM_RESOURCE_USB_PROD,
				    IPA_RM_RESOURCE_Q6_CONS);
	if (res < 0) {
		TETH_ERR("ipa_rm_add_dependency() failed.\n");
		goto bail;
	}

	/* this add_dependency call can't be sync since it will block until USB
	 * status is connected (which can happen only after the tethering
	 * bridge is connected), the clocks are already up so the call doesn't
	 * need to block.
	 */
	res = ipa_rm_add_dependency(IPA_RM_RESOURCE_Q6_PROD,
				    IPA_RM_RESOURCE_USB_CONS);
	if (res < 0 && res != -EINPROGRESS) {
		ipa_rm_delete_dependency(IPA_RM_RESOURCE_USB_PROD,
					IPA_RM_RESOURCE_Q6_CONS);
		TETH_ERR("ipa_rm_add_dependency() failed.\n");
		goto bail;
	}

	res = 0;

bail:
	TETH_DBG_FUNC_EXIT();
	return res;
}

static long ipa3_teth_bridge_ioctl(struct file *filp,
			      unsigned int cmd,
			      unsigned long arg)
{
	IPAERR("No ioctls are supported!\n");
	return -ENOIOCTLCMD;
}

static const struct file_operations ipa3_teth_bridge_drv_fops = {
	.owner = THIS_MODULE,
	.unlocked_ioctl = ipa3_teth_bridge_ioctl,
};

/**
* ipa3_teth_bridge_driver_init() - Initialize tethering bridge driver
*
*/
int ipa3_teth_bridge_driver_init(void)
{
	int res;

	TETH_DBG("Tethering bridge driver init\n");
	ipa3_teth_ctx = kzalloc(sizeof(*ipa3_teth_ctx), GFP_KERNEL);
	if (!ipa3_teth_ctx) {
		TETH_ERR("kzalloc err.\n");
		return -ENOMEM;
	}

	ipa3_teth_ctx->class = class_create(THIS_MODULE, TETH_BRIDGE_DRV_NAME);

	res = alloc_chrdev_region(&ipa3_teth_ctx->dev_num, 0, 1,
				  TETH_BRIDGE_DRV_NAME);
	if (res) {
		TETH_ERR("alloc_chrdev_region err.\n");
		res = -ENODEV;
		goto fail_alloc_chrdev_region;
	}

	ipa3_teth_ctx->dev = device_create(ipa3_teth_ctx->class,
			NULL,
			ipa3_teth_ctx->dev_num,
			ipa3_teth_ctx,
			TETH_BRIDGE_DRV_NAME);
	if (IS_ERR(ipa3_teth_ctx->dev)) {
		TETH_ERR(":device_create err.\n");
		res = -ENODEV;
		goto fail_device_create;
	}

	cdev_init(&ipa3_teth_ctx->cdev, &ipa3_teth_bridge_drv_fops);
	ipa3_teth_ctx->cdev.owner = THIS_MODULE;
	ipa3_teth_ctx->cdev.ops = &ipa3_teth_bridge_drv_fops;

	res = cdev_add(&ipa3_teth_ctx->cdev, ipa3_teth_ctx->dev_num, 1);
	if (res) {
		TETH_ERR(":cdev_add err=%d\n", -res);
		res = -ENODEV;
		goto fail_cdev_add;
	}
	TETH_DBG("Tethering bridge driver init OK\n");

	return 0;
fail_cdev_add:
	device_destroy(ipa3_teth_ctx->class, ipa3_teth_ctx->dev_num);
fail_device_create:
	unregister_chrdev_region(ipa3_teth_ctx->dev_num, 1);
fail_alloc_chrdev_region:
	kfree(ipa3_teth_ctx);
	ipa3_teth_ctx = NULL;

	return res;
}

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Tethering bridge driver");
