/*
 * Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved.
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 *
 * 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.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/usb.h>
#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/usb/cdc.h>
#include <linux/wait.h>
#include <linux/if_ether.h>
#include <linux/pm_runtime.h>

#include "gdm_usb.h"
#include "gdm_lte.h"
#include "hci.h"
#include "hci_packet.h"
#include "gdm_endian.h"

#define USB_DEVICE_CDC_DATA(vid, pid) \
	.match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
		USB_DEVICE_ID_MATCH_INT_CLASS | \
		USB_DEVICE_ID_MATCH_INT_SUBCLASS,\
	.idVendor = vid,\
	.idProduct = pid,\
	.bInterfaceClass = USB_CLASS_COMM,\
	.bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET

#define USB_DEVICE_MASS_DATA(vid, pid) \
	.match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
		USB_DEVICE_ID_MATCH_INT_INFO,\
	.idVendor = vid,\
	.idProduct = pid,\
	.bInterfaceSubClass = USB_SC_SCSI, \
	.bInterfaceClass = USB_CLASS_MASS_STORAGE,\
	.bInterfaceProtocol = USB_PR_BULK

static const struct usb_device_id id_table[] = {
	{ USB_DEVICE_CDC_DATA(VID_GCT, PID_GDM7240) }, /* GCT GDM7240 */
	{ USB_DEVICE_CDC_DATA(VID_GCT, PID_GDM7243) }, /* GCT GDM7243 */
	{ }
};

MODULE_DEVICE_TABLE(usb, id_table);

static struct workqueue_struct *usb_tx_wq;
static struct workqueue_struct *usb_rx_wq;

static void do_tx(struct work_struct *work);
static void do_rx(struct work_struct *work);

static int gdm_usb_recv(void *priv_dev,
			int (*cb)(void *cb_data,
				void *data, int len, int context),
			void *cb_data,
			int context);

static int request_mac_address(struct lte_udev *udev)
{
	u8 buf[16] = {0,};
	struct hci_packet *hci = (struct hci_packet *)buf;
	struct usb_device *usbdev = udev->usbdev;
	int actual;
	int ret = -1;

	hci->cmd_evt = gdm_cpu_to_dev16(&udev->gdm_ed, LTE_GET_INFORMATION);
	hci->len = gdm_cpu_to_dev16(&udev->gdm_ed, 1);
	hci->data[0] = MAC_ADDRESS;

	ret = usb_bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 2), buf, 5,
		     &actual, 1000);

	udev->request_mac_addr = 1;

	return ret;
}

static struct usb_tx *alloc_tx_struct(int len)
{
	struct usb_tx *t = NULL;
	int ret = 0;

	t = kzalloc(sizeof(struct usb_tx), GFP_ATOMIC);
	if (!t) {
		ret = -ENOMEM;
		goto out;
	}

	t->urb = usb_alloc_urb(0, GFP_ATOMIC);
	if (!(len % 512))
		len++;

	t->buf = kmalloc(len, GFP_ATOMIC);
	if (!t->urb || !t->buf) {
		ret = -ENOMEM;
		goto out;
	}

out:
	if (ret < 0) {
		if (t) {
			usb_free_urb(t->urb);
			kfree(t->buf);
			kfree(t);
		}
		return NULL;
	}

	return t;
}

static struct usb_tx_sdu *alloc_tx_sdu_struct(void)
{
	struct usb_tx_sdu *t_sdu;

	t_sdu = kzalloc(sizeof(struct usb_tx_sdu), GFP_ATOMIC);
	if (!t_sdu)
		return NULL;

	t_sdu->buf = kmalloc(SDU_BUF_SIZE, GFP_ATOMIC);
	if (!t_sdu->buf) {
		kfree(t_sdu);
		return NULL;
	}

	return t_sdu;
}

static void free_tx_struct(struct usb_tx *t)
{
	if (t) {
		usb_free_urb(t->urb);
		kfree(t->buf);
		kfree(t);
	}
}

static void free_tx_sdu_struct(struct usb_tx_sdu *t_sdu)
{
	if (t_sdu) {
		kfree(t_sdu->buf);
		kfree(t_sdu);
	}
}

static struct usb_tx_sdu *get_tx_sdu_struct(struct tx_cxt *tx, int *no_spc)
{
	struct usb_tx_sdu *t_sdu;

	if (list_empty(&tx->free_list))
		return NULL;

	t_sdu = list_entry(tx->free_list.next, struct usb_tx_sdu, list);
	list_del(&t_sdu->list);

	tx->avail_count--;

	*no_spc = list_empty(&tx->free_list) ? 1 : 0;

	return t_sdu;
}

static void put_tx_struct(struct tx_cxt *tx, struct usb_tx_sdu *t_sdu)
{
	list_add_tail(&t_sdu->list, &tx->free_list);
	tx->avail_count++;
}

static struct usb_rx *alloc_rx_struct(void)
{
	struct usb_rx *r = NULL;
	int ret = 0;

	r = kmalloc(sizeof(struct usb_rx), GFP_ATOMIC);
	if (!r) {
		ret = -ENOMEM;
		goto out;
	}

	r->urb = usb_alloc_urb(0, GFP_ATOMIC);
	r->buf = kmalloc(RX_BUF_SIZE, GFP_ATOMIC);
	if (!r->urb || !r->buf) {
		ret = -ENOMEM;
		goto out;
	}
out:

	if (ret < 0) {
		if (r) {
			usb_free_urb(r->urb);
			kfree(r->buf);
			kfree(r);
		}
		return NULL;
	}

	return r;
}

static void free_rx_struct(struct usb_rx *r)
{
	if (r) {
		usb_free_urb(r->urb);
		kfree(r->buf);
		kfree(r);
	}
}

static struct usb_rx *get_rx_struct(struct rx_cxt *rx, int *no_spc)
{
	struct usb_rx *r;
	unsigned long flags;

	spin_lock_irqsave(&rx->rx_lock, flags);

	if (list_empty(&rx->free_list)) {
		spin_unlock_irqrestore(&rx->rx_lock, flags);
		return NULL;
	}

	r = list_entry(rx->free_list.next, struct usb_rx, free_list);
	list_del(&r->free_list);

	rx->avail_count--;

	*no_spc = list_empty(&rx->free_list) ? 1 : 0;

	spin_unlock_irqrestore(&rx->rx_lock, flags);

	return r;
}

static void put_rx_struct(struct rx_cxt *rx, struct usb_rx *r)
{
	unsigned long flags;

	spin_lock_irqsave(&rx->rx_lock, flags);

	list_add_tail(&r->free_list, &rx->free_list);
	rx->avail_count++;

	spin_unlock_irqrestore(&rx->rx_lock, flags);
}

static void release_usb(struct lte_udev *udev)
{
	struct rx_cxt	*rx = &udev->rx;
	struct tx_cxt	*tx = &udev->tx;
	struct usb_tx	*t, *t_next;
	struct usb_rx	*r, *r_next;
	struct usb_tx_sdu	*t_sdu, *t_sdu_next;
	unsigned long flags;

	spin_lock_irqsave(&tx->lock, flags);
	list_for_each_entry_safe(t_sdu, t_sdu_next, &tx->sdu_list, list)
	{
		list_del(&t_sdu->list);
		free_tx_sdu_struct(t_sdu);
	}

	list_for_each_entry_safe(t, t_next, &tx->hci_list, list)
	{
		list_del(&t->list);
		free_tx_struct(t);
	}

	list_for_each_entry_safe(t_sdu, t_sdu_next, &tx->free_list, list)
	{
		list_del(&t_sdu->list);
		free_tx_sdu_struct(t_sdu);
	}
	spin_unlock_irqrestore(&tx->lock, flags);

	spin_lock_irqsave(&rx->submit_lock, flags);
	list_for_each_entry_safe(r, r_next, &rx->rx_submit_list, rx_submit_list)
	{
		spin_unlock_irqrestore(&rx->submit_lock, flags);
		usb_kill_urb(r->urb);
		spin_lock_irqsave(&rx->submit_lock, flags);
	}
	spin_unlock_irqrestore(&rx->submit_lock, flags);

	spin_lock_irqsave(&rx->rx_lock, flags);
	list_for_each_entry_safe(r, r_next, &rx->free_list, free_list)
	{
		list_del(&r->free_list);
		free_rx_struct(r);
	}
	spin_unlock_irqrestore(&rx->rx_lock, flags);

	spin_lock_irqsave(&rx->to_host_lock, flags);
	list_for_each_entry_safe(r, r_next, &rx->to_host_list, to_host_list)
	{
		if (r->index == (void *)udev) {
			list_del(&r->to_host_list);
			free_rx_struct(r);
		}
	}
	spin_unlock_irqrestore(&rx->to_host_lock, flags);
}

static int init_usb(struct lte_udev *udev)
{
	int ret = 0;
	int i;
	struct tx_cxt *tx = &udev->tx;
	struct rx_cxt *rx = &udev->rx;
	struct usb_tx_sdu *t_sdu = NULL;
	struct usb_rx *r = NULL;

	udev->send_complete = 1;
	udev->tx_stop = 0;
	udev->request_mac_addr = 0;
	udev->usb_state = PM_NORMAL;

	INIT_LIST_HEAD(&tx->sdu_list);
	INIT_LIST_HEAD(&tx->hci_list);
	INIT_LIST_HEAD(&tx->free_list);
	INIT_LIST_HEAD(&rx->rx_submit_list);
	INIT_LIST_HEAD(&rx->free_list);
	INIT_LIST_HEAD(&rx->to_host_list);
	spin_lock_init(&tx->lock);
	spin_lock_init(&rx->rx_lock);
	spin_lock_init(&rx->submit_lock);
	spin_lock_init(&rx->to_host_lock);

	tx->avail_count = 0;
	rx->avail_count = 0;

	udev->rx_cb = NULL;

	for (i = 0; i < MAX_NUM_SDU_BUF; i++) {
		t_sdu = alloc_tx_sdu_struct();
		if (t_sdu == NULL) {
			ret = -ENOMEM;
			goto fail;
		}

		list_add(&t_sdu->list, &tx->free_list);
		tx->avail_count++;
	}

	for (i = 0; i < MAX_RX_SUBMIT_COUNT*2; i++) {
		r = alloc_rx_struct();
		if (r == NULL) {
			ret = -ENOMEM;
			goto fail;
		}

		list_add(&r->free_list, &rx->free_list);
		rx->avail_count++;
	}
	INIT_DELAYED_WORK(&udev->work_tx, do_tx);
	INIT_DELAYED_WORK(&udev->work_rx, do_rx);
	return 0;
fail:
	return ret;
}

static int set_mac_address(u8 *data, void *arg)
{
	struct phy_dev *phy_dev = (struct phy_dev *)arg;
	struct lte_udev *udev = phy_dev->priv_dev;
	struct tlv *tlv = (struct tlv *)data;
	u8 mac_address[ETH_ALEN] = {0, };

	if (tlv->type == MAC_ADDRESS && udev->request_mac_addr) {
		memcpy(mac_address, tlv->data, tlv->len);

		if (register_lte_device(phy_dev,
				&udev->intf->dev, mac_address) < 0)
			pr_err("register lte device failed\n");

		udev->request_mac_addr = 0;

		return 1;
	}

	return 0;
}

static void do_rx(struct work_struct *work)
{
	struct lte_udev *udev =
		container_of(work, struct lte_udev, work_rx.work);
	struct rx_cxt *rx = &udev->rx;
	struct usb_rx *r;
	struct hci_packet *hci;
	struct phy_dev *phy_dev;
	u16 cmd_evt;
	int ret;
	unsigned long flags;

	while (1) {
		spin_lock_irqsave(&rx->to_host_lock, flags);
		if (list_empty(&rx->to_host_list)) {
			spin_unlock_irqrestore(&rx->to_host_lock, flags);
			break;
		}
		r = list_entry(rx->to_host_list.next,
			struct usb_rx, to_host_list);
		list_del(&r->to_host_list);
		spin_unlock_irqrestore(&rx->to_host_lock, flags);

		phy_dev = (struct phy_dev *)r->cb_data;
		udev = (struct lte_udev *)phy_dev->priv_dev;
		hci = (struct hci_packet *)r->buf;
		cmd_evt = gdm_dev16_to_cpu(&udev->gdm_ed, hci->cmd_evt);

		switch (cmd_evt) {
		case LTE_GET_INFORMATION_RESULT:
			if (set_mac_address(hci->data, r->cb_data) == 0) {
				ret = r->callback(r->cb_data,
						  r->buf,
						  r->urb->actual_length,
						  KERNEL_THREAD);
			}
			break;

		default:
			if (r->callback) {
				ret = r->callback(r->cb_data,
						  r->buf,
						  r->urb->actual_length,
						  KERNEL_THREAD);

				if (ret == -EAGAIN)
					pr_err("failed to send received data\n");
			}
			break;
		}

		put_rx_struct(rx, r);

		gdm_usb_recv(udev,
			     r->callback,
			     r->cb_data,
			     USB_COMPLETE);
	}
}

static void remove_rx_submit_list(struct usb_rx *r, struct rx_cxt *rx)
{
	unsigned long flags;
	struct usb_rx	*r_remove, *r_remove_next;

	spin_lock_irqsave(&rx->submit_lock, flags);
	list_for_each_entry_safe(r_remove,
			r_remove_next, &rx->rx_submit_list, rx_submit_list)
	{
		if (r == r_remove) {
			list_del(&r->rx_submit_list);
			break;
		}
	}
	spin_unlock_irqrestore(&rx->submit_lock, flags);
}

static void gdm_usb_rcv_complete(struct urb *urb)
{
	struct usb_rx *r = urb->context;
	struct rx_cxt *rx = r->rx;
	unsigned long flags;
	struct lte_udev *udev = container_of(r->rx, struct lte_udev, rx);
	struct usb_device *usbdev = udev->usbdev;

	remove_rx_submit_list(r, rx);

	if (!urb->status && r->callback) {
		spin_lock_irqsave(&rx->to_host_lock, flags);
		list_add_tail(&r->to_host_list, &rx->to_host_list);
		queue_work(usb_rx_wq, &udev->work_rx.work);
		spin_unlock_irqrestore(&rx->to_host_lock, flags);
	} else {
		if (urb->status && udev->usb_state == PM_NORMAL)
			pr_err("%s: urb status error %d\n",
			       __func__, urb->status);

		put_rx_struct(rx, r);
	}

	usb_mark_last_busy(usbdev);
}

static int gdm_usb_recv(void *priv_dev,
			int (*cb)(void *cb_data,
				void *data, int len, int context),
			void *cb_data,
			int context)
{
	struct lte_udev *udev = priv_dev;
	struct usb_device *usbdev = udev->usbdev;
	struct rx_cxt *rx = &udev->rx;
	struct usb_rx *r;
	int no_spc;
	int ret;
	unsigned long flags;

	if (!udev->usbdev) {
		pr_err("invalid device\n");
		return -ENODEV;
	}

	r = get_rx_struct(rx, &no_spc);
	if (!r) {
		pr_err("Out of Memory\n");
		return -ENOMEM;
	}

	udev->rx_cb = cb;
	r->callback = cb;
	r->cb_data = cb_data;
	r->index = (void *)udev;
	r->rx = rx;

	usb_fill_bulk_urb(r->urb,
			  usbdev,
			  usb_rcvbulkpipe(usbdev, 0x83),
			  r->buf,
			  RX_BUF_SIZE,
			  gdm_usb_rcv_complete,
			  r);

	spin_lock_irqsave(&rx->submit_lock, flags);
	list_add_tail(&r->rx_submit_list, &rx->rx_submit_list);
	spin_unlock_irqrestore(&rx->submit_lock, flags);

	if (context == KERNEL_THREAD)
		ret = usb_submit_urb(r->urb, GFP_KERNEL);
	else
		ret = usb_submit_urb(r->urb, GFP_ATOMIC);

	if (ret) {
		spin_lock_irqsave(&rx->submit_lock, flags);
		list_del(&r->rx_submit_list);
		spin_unlock_irqrestore(&rx->submit_lock, flags);

		pr_err("usb_submit_urb failed (%p)\n", r);
		put_rx_struct(rx, r);
	}

	return ret;
}

static void gdm_usb_send_complete(struct urb *urb)
{
	struct usb_tx *t = urb->context;
	struct tx_cxt *tx = t->tx;
	struct lte_udev *udev = container_of(tx, struct lte_udev, tx);
	unsigned long flags;

	if (urb->status == -ECONNRESET) {
		pr_info("CONNRESET\n");
		return;
	}

	if (t->callback)
		t->callback(t->cb_data);

	free_tx_struct(t);

	spin_lock_irqsave(&tx->lock, flags);
	udev->send_complete = 1;
	queue_work(usb_tx_wq, &udev->work_tx.work);
	spin_unlock_irqrestore(&tx->lock, flags);
}

static int send_tx_packet(struct usb_device *usbdev, struct usb_tx *t, u32 len)
{
	int ret = 0;

	if (!(len%512))
		len++;

	usb_fill_bulk_urb(t->urb,
			  usbdev,
			  usb_sndbulkpipe(usbdev, 2),
			  t->buf,
			  len,
			  gdm_usb_send_complete,
			  t);

	ret = usb_submit_urb(t->urb, GFP_ATOMIC);

	if (ret)
		pr_err("usb_submit_urb failed: %d\n", ret);

	usb_mark_last_busy(usbdev);

	return ret;
}

static u32 packet_aggregation(struct lte_udev *udev, u8 *send_buf)
{
	struct tx_cxt *tx = &udev->tx;
	struct usb_tx_sdu *t_sdu = NULL;
	struct multi_sdu *multi_sdu = (struct multi_sdu *)send_buf;
	u16 send_len = 0;
	u16 num_packet = 0;
	unsigned long flags;

	multi_sdu->cmd_evt = gdm_cpu_to_dev16(&udev->gdm_ed, LTE_TX_MULTI_SDU);

	while (num_packet < MAX_PACKET_IN_MULTI_SDU) {
		spin_lock_irqsave(&tx->lock, flags);
		if (list_empty(&tx->sdu_list)) {
			spin_unlock_irqrestore(&tx->lock, flags);
			break;
		}

		t_sdu = list_entry(tx->sdu_list.next, struct usb_tx_sdu, list);
		if (send_len + t_sdu->len > MAX_SDU_SIZE) {
			spin_unlock_irqrestore(&tx->lock, flags);
			break;
		}

		list_del(&t_sdu->list);
		spin_unlock_irqrestore(&tx->lock, flags);

		memcpy(multi_sdu->data + send_len, t_sdu->buf, t_sdu->len);

		send_len += (t_sdu->len + 3) & 0xfffc;
		num_packet++;

		if (tx->avail_count > 10)
			t_sdu->callback(t_sdu->cb_data);

		spin_lock_irqsave(&tx->lock, flags);
		put_tx_struct(tx, t_sdu);
		spin_unlock_irqrestore(&tx->lock, flags);
	}

	multi_sdu->len = gdm_cpu_to_dev16(&udev->gdm_ed, send_len);
	multi_sdu->num_packet = gdm_cpu_to_dev16(&udev->gdm_ed, num_packet);

	return send_len + offsetof(struct multi_sdu, data);
}

static void do_tx(struct work_struct *work)
{
	struct lte_udev *udev =
		container_of(work, struct lte_udev, work_tx.work);
	struct usb_device *usbdev = udev->usbdev;
	struct tx_cxt *tx = &udev->tx;
	struct usb_tx *t = NULL;
	int is_send = 0;
	u32 len = 0;
	unsigned long flags;

	if (!usb_autopm_get_interface(udev->intf))
		usb_autopm_put_interface(udev->intf);

	if (udev->usb_state == PM_SUSPEND)
		return;

	spin_lock_irqsave(&tx->lock, flags);
	if (!udev->send_complete) {
		spin_unlock_irqrestore(&tx->lock, flags);
		return;
	} else {
		udev->send_complete = 0;
	}

	if (!list_empty(&tx->hci_list)) {
		t = list_entry(tx->hci_list.next, struct usb_tx, list);
		list_del(&t->list);
		len = t->len;
		t->is_sdu = 0;
		is_send = 1;
	} else if (!list_empty(&tx->sdu_list)) {
		if (udev->tx_stop) {
			udev->send_complete = 1;
			spin_unlock_irqrestore(&tx->lock, flags);
			return;
		}

		t = alloc_tx_struct(TX_BUF_SIZE);
		t->callback = NULL;
		t->tx = tx;
		t->is_sdu = 1;
		is_send = 1;
	}

	if (!is_send) {
		udev->send_complete = 1;
		spin_unlock_irqrestore(&tx->lock, flags);
		return;
	}
	spin_unlock_irqrestore(&tx->lock, flags);

	if (t->is_sdu)
		len = packet_aggregation(udev, t->buf);

	if (send_tx_packet(usbdev, t, len)) {
		pr_err("send_tx_packet failed\n");
		t->callback = NULL;
		gdm_usb_send_complete(t->urb);
	}
}

#define SDU_PARAM_LEN 12
static int gdm_usb_sdu_send(void *priv_dev, void *data, int len,
				unsigned int dftEpsId, unsigned int epsId,
				void (*cb)(void *data), void *cb_data,
			    int dev_idx, int nic_type)
{
	struct lte_udev *udev = priv_dev;
	struct tx_cxt *tx = &udev->tx;
	struct usb_tx_sdu *t_sdu;
	struct sdu *sdu = NULL;
	unsigned long flags;
	int no_spc = 0;
	u16 send_len;

	if (!udev->usbdev) {
		pr_err("sdu send - invalid device\n");
		return TX_NO_DEV;
	}

	spin_lock_irqsave(&tx->lock, flags);
	t_sdu = get_tx_sdu_struct(tx, &no_spc);
	spin_unlock_irqrestore(&tx->lock, flags);

	if (t_sdu == NULL) {
		pr_err("sdu send - free list empty\n");
		return TX_NO_SPC;
	}

	sdu = (struct sdu *)t_sdu->buf;
	sdu->cmd_evt = gdm_cpu_to_dev16(&udev->gdm_ed, LTE_TX_SDU);
	if (nic_type == NIC_TYPE_ARP) {
		send_len = len + SDU_PARAM_LEN;
	    memcpy(sdu->data, data, len);
	} else {
	    send_len = len - ETH_HLEN;
	    send_len += SDU_PARAM_LEN;
	    memcpy(sdu->data, data+ETH_HLEN, len-ETH_HLEN);
	}

	sdu->len = gdm_cpu_to_dev16(&udev->gdm_ed, send_len);
	sdu->dftEpsId = gdm_cpu_to_dev32(&udev->gdm_ed, dftEpsId);
	sdu->bearer_ID = gdm_cpu_to_dev32(&udev->gdm_ed, epsId);
	sdu->nic_type = gdm_cpu_to_dev32(&udev->gdm_ed, nic_type);

	t_sdu->len = send_len + HCI_HEADER_SIZE;
	t_sdu->callback = cb;
	t_sdu->cb_data = cb_data;

	spin_lock_irqsave(&tx->lock, flags);
	list_add_tail(&t_sdu->list, &tx->sdu_list);
	queue_work(usb_tx_wq, &udev->work_tx.work);
	spin_unlock_irqrestore(&tx->lock, flags);

	if (no_spc)
		return TX_NO_BUFFER;

	return 0;
}

static int gdm_usb_hci_send(void *priv_dev, void *data, int len,
			void (*cb)(void *data), void *cb_data)
{
	struct lte_udev *udev = priv_dev;
	struct tx_cxt *tx = &udev->tx;
	struct usb_tx *t;
	unsigned long flags;

	if (!udev->usbdev) {
		pr_err("hci send - invalid device\n");
		return -ENODEV;
	}

	t = alloc_tx_struct(len);
	if (t == NULL) {
		pr_err("hci_send - out of memory\n");
		return -ENOMEM;
	}

	memcpy(t->buf, data, len);
	t->callback = cb;
	t->cb_data = cb_data;
	t->len = len;
	t->tx = tx;
	t->is_sdu = 0;

	spin_lock_irqsave(&tx->lock, flags);
	list_add_tail(&t->list, &tx->hci_list);
	queue_work(usb_tx_wq, &udev->work_tx.work);
	spin_unlock_irqrestore(&tx->lock, flags);

	return 0;
}

static struct gdm_endian *gdm_usb_get_endian(void *priv_dev)
{
	struct lte_udev *udev = priv_dev;

	return &udev->gdm_ed;
}

static int gdm_usb_probe(struct usb_interface *intf,
	const struct usb_device_id *id)
{
	int ret = 0;
	struct phy_dev *phy_dev = NULL;
	struct lte_udev *udev = NULL;
	u16 idVendor, idProduct;
	int bInterfaceNumber;
	struct usb_device *usbdev = interface_to_usbdev(intf);

	bInterfaceNumber = intf->cur_altsetting->desc.bInterfaceNumber;
	idVendor = __le16_to_cpu(usbdev->descriptor.idVendor);
	idProduct = __le16_to_cpu(usbdev->descriptor.idProduct);

	pr_info("net vid = 0x%04x pid = 0x%04x\n", idVendor, idProduct);

	if (bInterfaceNumber > NETWORK_INTERFACE) {
		pr_info("not a network device\n");
		return -ENODEV;
	}

	phy_dev = kzalloc(sizeof(struct phy_dev), GFP_KERNEL);
	if (!phy_dev)
		return -ENOMEM;

	udev = kzalloc(sizeof(struct lte_udev), GFP_KERNEL);
	if (!udev) {
		ret = -ENOMEM;
		goto err_udev;
	}

	phy_dev->priv_dev = (void *)udev;
	phy_dev->send_hci_func = gdm_usb_hci_send;
	phy_dev->send_sdu_func = gdm_usb_sdu_send;
	phy_dev->rcv_func = gdm_usb_recv;
	phy_dev->get_endian = gdm_usb_get_endian;

	udev->usbdev = usbdev;
	ret = init_usb(udev);
	if (ret < 0) {
		pr_err("init_usb func failed\n");
		goto err_init_usb;
	}
	udev->intf = intf;

	intf->needs_remote_wakeup = 1;
	usb_enable_autosuspend(usbdev);
	pm_runtime_set_autosuspend_delay(&usbdev->dev, AUTO_SUSPEND_TIMER);

	/* List up hosts with big endians, otherwise,
	 * defaults to little endian
	 */
	if (idProduct == PID_GDM7243)
		gdm_set_endian(&udev->gdm_ed, ENDIANNESS_BIG);
	else
		gdm_set_endian(&udev->gdm_ed, ENDIANNESS_LITTLE);

	ret = request_mac_address(udev);
	if (ret < 0) {
		pr_err("request Mac address failed\n");
		goto err_mac_address;
	}

	start_rx_proc(phy_dev);
	usb_get_dev(usbdev);
	usb_set_intfdata(intf, phy_dev);

	return 0;

err_mac_address:
	release_usb(udev);
err_init_usb:
	kfree(udev);
err_udev:
	kfree(phy_dev);

	return ret;
}

static void gdm_usb_disconnect(struct usb_interface *intf)
{
	struct phy_dev *phy_dev;
	struct lte_udev *udev;
	u16 idVendor, idProduct;
	struct usb_device *usbdev;
	usbdev = interface_to_usbdev(intf);

	idVendor = __le16_to_cpu(usbdev->descriptor.idVendor);
	idProduct = __le16_to_cpu(usbdev->descriptor.idProduct);

	phy_dev = usb_get_intfdata(intf);

	udev = phy_dev->priv_dev;
	unregister_lte_device(phy_dev);

	release_usb(udev);

	kfree(udev);
	udev = NULL;

	kfree(phy_dev);
	phy_dev = NULL;

	usb_put_dev(usbdev);
}

static int gdm_usb_suspend(struct usb_interface *intf, pm_message_t pm_msg)
{
	struct phy_dev *phy_dev;
	struct lte_udev *udev;
	struct rx_cxt *rx;
	struct usb_rx *r;
	struct usb_rx *r_next;
	unsigned long flags;

	phy_dev = usb_get_intfdata(intf);
	udev = phy_dev->priv_dev;
	rx = &udev->rx;
	if (udev->usb_state != PM_NORMAL) {
		pr_err("usb suspend - invalid state\n");
		return -1;
	}

	udev->usb_state = PM_SUSPEND;

	spin_lock_irqsave(&rx->submit_lock, flags);
	list_for_each_entry_safe(r, r_next, &rx->rx_submit_list, rx_submit_list)
	{
		spin_unlock_irqrestore(&rx->submit_lock, flags);
		usb_kill_urb(r->urb);
		spin_lock_irqsave(&rx->submit_lock, flags);
	}
	spin_unlock_irqrestore(&rx->submit_lock, flags);

	return 0;
}

static int gdm_usb_resume(struct usb_interface *intf)
{
	struct phy_dev *phy_dev;
	struct lte_udev *udev;
	struct tx_cxt *tx;
	struct rx_cxt *rx;
	unsigned long flags;
	int issue_count;
	int i;

	phy_dev = usb_get_intfdata(intf);
	udev = phy_dev->priv_dev;
	rx = &udev->rx;

	if (udev->usb_state != PM_SUSPEND) {
		pr_err("usb resume - invalid state\n");
		return -1;
	}
	udev->usb_state = PM_NORMAL;

	spin_lock_irqsave(&rx->rx_lock, flags);
	issue_count = rx->avail_count - MAX_RX_SUBMIT_COUNT;
	spin_unlock_irqrestore(&rx->rx_lock, flags);

	if (issue_count >= 0) {
		for (i = 0; i < issue_count; i++)
			gdm_usb_recv(phy_dev->priv_dev,
				     udev->rx_cb,
				     phy_dev,
				     USB_COMPLETE);
	}

	tx = &udev->tx;
	spin_lock_irqsave(&tx->lock, flags);
	queue_work(usb_tx_wq, &udev->work_tx.work);
	spin_unlock_irqrestore(&tx->lock, flags);

	return 0;
}

static struct usb_driver gdm_usb_lte_driver = {
	.name = "gdm_lte",
	.probe = gdm_usb_probe,
	.disconnect = gdm_usb_disconnect,
	.id_table = id_table,
	.supports_autosuspend = 1,
	.suspend = gdm_usb_suspend,
	.resume = gdm_usb_resume,
	.reset_resume = gdm_usb_resume,
};

static int __init gdm_usb_lte_init(void)
{
	if (gdm_lte_event_init() < 0) {
		pr_err("error creating event\n");
		return -1;
	}

	usb_tx_wq = create_workqueue("usb_tx_wq");
	if (usb_tx_wq == NULL)
		return -1;

	usb_rx_wq = create_workqueue("usb_rx_wq");
	if (usb_rx_wq == NULL)
		return -1;

	return usb_register(&gdm_usb_lte_driver);
}

static void __exit gdm_usb_lte_exit(void)
{
	gdm_lte_event_exit();

	usb_deregister(&gdm_usb_lte_driver);

	if (usb_tx_wq) {
		flush_workqueue(usb_tx_wq);
		destroy_workqueue(usb_tx_wq);
	}

	if (usb_rx_wq) {
		flush_workqueue(usb_rx_wq);
		destroy_workqueue(usb_rx_wq);
	}
}

module_init(gdm_usb_lte_init);
module_exit(gdm_usb_lte_exit);

MODULE_VERSION(DRIVER_VERSION);
MODULE_DESCRIPTION("GCT LTE USB Device Driver");
MODULE_LICENSE("GPL");
