/*
 *  Copyright (C) 2008, cozybit Inc.
 *  Copyright (C) 2003-2006, Marvell International Ltd.
 *
 *  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.
 */
#define DRV_NAME "lbtf_usb"

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include "libertas_tf.h"
#include "if_usb.h"

#include <linux/delay.h>
#include <linux/module.h>
#include <linux/firmware.h>
#include <linux/netdevice.h>
#include <linux/slab.h>
#include <linux/usb.h>

#define INSANEDEBUG	0
#define lbtf_deb_usb2(...) do { if (INSANEDEBUG) lbtf_deb_usbd(__VA_ARGS__); } while (0)

#define MESSAGE_HEADER_LEN	4

static char *lbtf_fw_name = "lbtf_usb.bin";
module_param_named(fw_name, lbtf_fw_name, charp, 0644);

MODULE_FIRMWARE("lbtf_usb.bin");

static struct usb_device_id if_usb_table[] = {
	/* Enter the device signature inside */
	{ USB_DEVICE(0x1286, 0x2001) },
	{ USB_DEVICE(0x05a3, 0x8388) },
	{}	/* Terminating entry */
};

MODULE_DEVICE_TABLE(usb, if_usb_table);

static void if_usb_receive(struct urb *urb);
static void if_usb_receive_fwload(struct urb *urb);
static int if_usb_prog_firmware(struct if_usb_card *cardp);
static int if_usb_host_to_card(struct lbtf_private *priv, uint8_t type,
			       uint8_t *payload, uint16_t nb);
static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload,
			uint16_t nb, u8 data);
static void if_usb_free(struct if_usb_card *cardp);
static int if_usb_submit_rx_urb(struct if_usb_card *cardp);
static int if_usb_reset_device(struct if_usb_card *cardp);

/**
 *  if_usb_wrike_bulk_callback -  call back to handle URB status
 *
 *  @param urb		pointer to urb structure
 */
static void if_usb_write_bulk_callback(struct urb *urb)
{
	if (urb->status != 0) {
		/* print the failure status number for debug */
		pr_info("URB in failure status: %d\n", urb->status);
	} else {
		lbtf_deb_usb2(&urb->dev->dev, "URB status is successful\n");
		lbtf_deb_usb2(&urb->dev->dev, "Actual length transmitted %d\n",
			     urb->actual_length);
	}
}

/**
 *  if_usb_free - free tx/rx urb, skb and rx buffer
 *
 *  @param cardp	pointer if_usb_card
 */
static void if_usb_free(struct if_usb_card *cardp)
{
	lbtf_deb_enter(LBTF_DEB_USB);

	/* Unlink tx & rx urb */
	usb_kill_urb(cardp->tx_urb);
	usb_kill_urb(cardp->rx_urb);
	usb_kill_urb(cardp->cmd_urb);

	usb_free_urb(cardp->tx_urb);
	cardp->tx_urb = NULL;

	usb_free_urb(cardp->rx_urb);
	cardp->rx_urb = NULL;

	usb_free_urb(cardp->cmd_urb);
	cardp->cmd_urb = NULL;

	kfree(cardp->ep_out_buf);
	cardp->ep_out_buf = NULL;

	lbtf_deb_leave(LBTF_DEB_USB);
}

static void if_usb_setup_firmware(struct lbtf_private *priv)
{
	struct if_usb_card *cardp = priv->card;
	struct cmd_ds_set_boot2_ver b2_cmd;

	lbtf_deb_enter(LBTF_DEB_USB);

	if_usb_submit_rx_urb(cardp);
	b2_cmd.hdr.size = cpu_to_le16(sizeof(b2_cmd));
	b2_cmd.action = 0;
	b2_cmd.version = cardp->boot2_version;

	if (lbtf_cmd_with_response(priv, CMD_SET_BOOT2_VER, &b2_cmd))
		lbtf_deb_usb("Setting boot2 version failed\n");

	lbtf_deb_leave(LBTF_DEB_USB);
}

static void if_usb_fw_timeo(unsigned long priv)
{
	struct if_usb_card *cardp = (void *)priv;

	lbtf_deb_enter(LBTF_DEB_USB);
	if (!cardp->fwdnldover) {
		/* Download timed out */
		cardp->priv->surpriseremoved = 1;
		pr_err("Download timed out\n");
	} else {
		lbtf_deb_usb("Download complete, no event. Assuming success\n");
	}
	wake_up(&cardp->fw_wq);
	lbtf_deb_leave(LBTF_DEB_USB);
}

/**
 *  if_usb_probe - sets the configuration values
 *
 *  @ifnum	interface number
 *  @id		pointer to usb_device_id
 *
 *  Returns: 0 on success, error code on failure
 */
static int if_usb_probe(struct usb_interface *intf,
			const struct usb_device_id *id)
{
	struct usb_device *udev;
	struct usb_host_interface *iface_desc;
	struct usb_endpoint_descriptor *endpoint;
	struct lbtf_private *priv;
	struct if_usb_card *cardp;
	int i;

	lbtf_deb_enter(LBTF_DEB_USB);
	udev = interface_to_usbdev(intf);

	cardp = kzalloc(sizeof(struct if_usb_card), GFP_KERNEL);
	if (!cardp)
		goto error;

	setup_timer(&cardp->fw_timeout, if_usb_fw_timeo, (unsigned long)cardp);
	init_waitqueue_head(&cardp->fw_wq);

	cardp->udev = udev;
	iface_desc = intf->cur_altsetting;

	lbtf_deb_usbd(&udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X"
		     " bDeviceSubClass = 0x%X, bDeviceProtocol = 0x%X\n",
		     le16_to_cpu(udev->descriptor.bcdUSB),
		     udev->descriptor.bDeviceClass,
		     udev->descriptor.bDeviceSubClass,
		     udev->descriptor.bDeviceProtocol);

	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
		endpoint = &iface_desc->endpoint[i].desc;
		if (usb_endpoint_is_bulk_in(endpoint)) {
			cardp->ep_in_size =
				le16_to_cpu(endpoint->wMaxPacketSize);
			cardp->ep_in = usb_endpoint_num(endpoint);

			lbtf_deb_usbd(&udev->dev, "in_endpoint = %d\n",
				cardp->ep_in);
			lbtf_deb_usbd(&udev->dev, "Bulk in size is %d\n",
				cardp->ep_in_size);
		} else if (usb_endpoint_is_bulk_out(endpoint)) {
			cardp->ep_out_size =
				le16_to_cpu(endpoint->wMaxPacketSize);
			cardp->ep_out = usb_endpoint_num(endpoint);

			lbtf_deb_usbd(&udev->dev, "out_endpoint = %d\n",
				cardp->ep_out);
			lbtf_deb_usbd(&udev->dev, "Bulk out size is %d\n",
				cardp->ep_out_size);
		}
	}
	if (!cardp->ep_out_size || !cardp->ep_in_size) {
		lbtf_deb_usbd(&udev->dev, "Endpoints not found\n");
		/* Endpoints not found */
		goto dealloc;
	}

	cardp->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!cardp->rx_urb)
		goto dealloc;

	cardp->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!cardp->tx_urb)
		goto dealloc;

	cardp->cmd_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!cardp->cmd_urb)
		goto dealloc;

	cardp->ep_out_buf = kmalloc(MRVDRV_ETH_TX_PACKET_BUFFER_SIZE,
				    GFP_KERNEL);
	if (!cardp->ep_out_buf) {
		lbtf_deb_usbd(&udev->dev, "Could not allocate buffer\n");
		goto dealloc;
	}

	priv = lbtf_add_card(cardp, &udev->dev);
	if (!priv)
		goto dealloc;

	cardp->priv = priv;

	priv->hw_host_to_card = if_usb_host_to_card;
	priv->hw_prog_firmware = if_usb_prog_firmware;
	priv->hw_reset_device = if_usb_reset_device;
	cardp->boot2_version = udev->descriptor.bcdDevice;

	usb_get_dev(udev);
	usb_set_intfdata(intf, cardp);

	return 0;

dealloc:
	if_usb_free(cardp);
error:
lbtf_deb_leave(LBTF_DEB_MAIN);
	return -ENOMEM;
}

/**
 *  if_usb_disconnect -  free resource and cleanup
 *
 *  @intf	USB interface structure
 */
static void if_usb_disconnect(struct usb_interface *intf)
{
	struct if_usb_card *cardp = usb_get_intfdata(intf);
	struct lbtf_private *priv = cardp->priv;

	lbtf_deb_enter(LBTF_DEB_MAIN);

	if_usb_reset_device(cardp);

	if (priv)
		lbtf_remove_card(priv);

	/* Unlink and free urb */
	if_usb_free(cardp);

	usb_set_intfdata(intf, NULL);
	usb_put_dev(interface_to_usbdev(intf));

	lbtf_deb_leave(LBTF_DEB_MAIN);
}

/**
 *  if_usb_send_fw_pkt -  This function downloads the FW
 *
 *  @priv	pointer to struct lbtf_private
 *
 *  Returns: 0
 */
static int if_usb_send_fw_pkt(struct if_usb_card *cardp)
{
	struct fwdata *fwdata = cardp->ep_out_buf;
	u8 *firmware = (u8 *) cardp->fw->data;

	lbtf_deb_enter(LBTF_DEB_FW);

	/* If we got a CRC failure on the last block, back
	   up and retry it */
	if (!cardp->CRC_OK) {
		cardp->totalbytes = cardp->fwlastblksent;
		cardp->fwseqnum--;
	}

	lbtf_deb_usb2(&cardp->udev->dev, "totalbytes = %d\n",
		     cardp->totalbytes);

	/* struct fwdata (which we sent to the card) has an
	   extra __le32 field in between the header and the data,
	   which is not in the struct fwheader in the actual
	   firmware binary. Insert the seqnum in the middle... */
	memcpy(&fwdata->hdr, &firmware[cardp->totalbytes],
	       sizeof(struct fwheader));

	cardp->fwlastblksent = cardp->totalbytes;
	cardp->totalbytes += sizeof(struct fwheader);

	memcpy(fwdata->data, &firmware[cardp->totalbytes],
	       le32_to_cpu(fwdata->hdr.datalength));

	lbtf_deb_usb2(&cardp->udev->dev, "Data length = %d\n",
		     le32_to_cpu(fwdata->hdr.datalength));

	fwdata->seqnum = cpu_to_le32(++cardp->fwseqnum);
	cardp->totalbytes += le32_to_cpu(fwdata->hdr.datalength);

	usb_tx_block(cardp, cardp->ep_out_buf, sizeof(struct fwdata) +
		     le32_to_cpu(fwdata->hdr.datalength), 0);

	if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_DATA_TO_RECV)) {
		lbtf_deb_usb2(&cardp->udev->dev, "There are data to follow\n");
		lbtf_deb_usb2(&cardp->udev->dev,
			"seqnum = %d totalbytes = %d\n",
			cardp->fwseqnum, cardp->totalbytes);
	} else if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) {
		lbtf_deb_usb2(&cardp->udev->dev,
			"Host has finished FW downloading\n");
		lbtf_deb_usb2(&cardp->udev->dev, "Donwloading FW JUMP BLOCK\n");

		/* Host has finished FW downloading
		 * Donwloading FW JUMP BLOCK
		 */
		cardp->fwfinalblk = 1;
	}

	lbtf_deb_usb2(&cardp->udev->dev, "Firmware download done; size %d\n",
		     cardp->totalbytes);

	lbtf_deb_leave(LBTF_DEB_FW);
	return 0;
}

static int if_usb_reset_device(struct if_usb_card *cardp)
{
	struct cmd_ds_802_11_reset *cmd = cardp->ep_out_buf + 4;
	int ret;

	lbtf_deb_enter(LBTF_DEB_USB);

	*(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST);

	cmd->hdr.command = cpu_to_le16(CMD_802_11_RESET);
	cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_802_11_reset));
	cmd->hdr.result = cpu_to_le16(0);
	cmd->hdr.seqnum = cpu_to_le16(0x5a5a);
	cmd->action = cpu_to_le16(CMD_ACT_HALT);
	usb_tx_block(cardp, cardp->ep_out_buf,
		     4 + sizeof(struct cmd_ds_802_11_reset), 0);

	msleep(100);
	ret = usb_reset_device(cardp->udev);
	msleep(100);

	lbtf_deb_leave_args(LBTF_DEB_USB, "ret %d", ret);

	return ret;
}

/**
 *  usb_tx_block - transfer data to the device
 *
 *  @priv	pointer to struct lbtf_private
 *  @payload	pointer to payload data
 *  @nb		data length
 *  @data	non-zero for data, zero for commands
 *
 *  Returns: 0 on success, nonzero otherwise.
 */
static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload,
			uint16_t nb, u8 data)
{
	int ret = -1;
	struct urb *urb;

	lbtf_deb_enter(LBTF_DEB_USB);
	/* check if device is removed */
	if (cardp->priv->surpriseremoved) {
		lbtf_deb_usbd(&cardp->udev->dev, "Device removed\n");
		goto tx_ret;
	}

	if (data)
		urb = cardp->tx_urb;
	else
		urb = cardp->cmd_urb;

	usb_fill_bulk_urb(urb, cardp->udev,
			  usb_sndbulkpipe(cardp->udev,
					  cardp->ep_out),
			  payload, nb, if_usb_write_bulk_callback, cardp);

	urb->transfer_flags |= URB_ZERO_PACKET;

	if (usb_submit_urb(urb, GFP_ATOMIC)) {
		lbtf_deb_usbd(&cardp->udev->dev,
			"usb_submit_urb failed: %d\n", ret);
		goto tx_ret;
	}

	lbtf_deb_usb2(&cardp->udev->dev, "usb_submit_urb success\n");

	ret = 0;

tx_ret:
	lbtf_deb_leave(LBTF_DEB_USB);
	return ret;
}

static int __if_usb_submit_rx_urb(struct if_usb_card *cardp,
				  void (*callbackfn)(struct urb *urb))
{
	struct sk_buff *skb;
	int ret = -1;

	lbtf_deb_enter(LBTF_DEB_USB);

	skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE);
	if (!skb) {
		pr_err("No free skb\n");
		lbtf_deb_leave(LBTF_DEB_USB);
		return -1;
	}

	cardp->rx_skb = skb;

	/* Fill the receive configuration URB and initialise the Rx call back */
	usb_fill_bulk_urb(cardp->rx_urb, cardp->udev,
			  usb_rcvbulkpipe(cardp->udev, cardp->ep_in),
			  skb_tail_pointer(skb),
			  MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, callbackfn, cardp);

	cardp->rx_urb->transfer_flags |= URB_ZERO_PACKET;

	lbtf_deb_usb2(&cardp->udev->dev, "Pointer for rx_urb %p\n",
		cardp->rx_urb);
	ret = usb_submit_urb(cardp->rx_urb, GFP_ATOMIC);
	if (ret) {
		lbtf_deb_usbd(&cardp->udev->dev,
			"Submit Rx URB failed: %d\n", ret);
		kfree_skb(skb);
		cardp->rx_skb = NULL;
		lbtf_deb_leave(LBTF_DEB_USB);
		return -1;
	} else {
		lbtf_deb_usb2(&cardp->udev->dev, "Submit Rx URB success\n");
		lbtf_deb_leave(LBTF_DEB_USB);
		return 0;
	}
}

static int if_usb_submit_rx_urb_fwload(struct if_usb_card *cardp)
{
	return __if_usb_submit_rx_urb(cardp, &if_usb_receive_fwload);
}

static int if_usb_submit_rx_urb(struct if_usb_card *cardp)
{
	return __if_usb_submit_rx_urb(cardp, &if_usb_receive);
}

static void if_usb_receive_fwload(struct urb *urb)
{
	struct if_usb_card *cardp = urb->context;
	struct sk_buff *skb = cardp->rx_skb;
	struct fwsyncheader *syncfwheader;
	struct bootcmdresp bcmdresp;

	lbtf_deb_enter(LBTF_DEB_USB);
	if (urb->status) {
		lbtf_deb_usbd(&cardp->udev->dev,
			     "URB status is failed during fw load\n");
		kfree_skb(skb);
		lbtf_deb_leave(LBTF_DEB_USB);
		return;
	}

	if (cardp->fwdnldover) {
		__le32 *tmp = (__le32 *)(skb->data);

		if (tmp[0] == cpu_to_le32(CMD_TYPE_INDICATION) &&
		    tmp[1] == cpu_to_le32(MACREG_INT_CODE_FIRMWARE_READY)) {
			/* Firmware ready event received */
			pr_info("Firmware ready event received\n");
			wake_up(&cardp->fw_wq);
		} else {
			lbtf_deb_usb("Waiting for confirmation; got %x %x\n",
				    le32_to_cpu(tmp[0]), le32_to_cpu(tmp[1]));
			if_usb_submit_rx_urb_fwload(cardp);
		}
		kfree_skb(skb);
		lbtf_deb_leave(LBTF_DEB_USB);
		return;
	}
	if (cardp->bootcmdresp <= 0) {
		memcpy(&bcmdresp, skb->data, sizeof(bcmdresp));

		if (le16_to_cpu(cardp->udev->descriptor.bcdDevice) < 0x3106) {
			kfree_skb(skb);
			if_usb_submit_rx_urb_fwload(cardp);
			cardp->bootcmdresp = 1;
			/* Received valid boot command response */
			lbtf_deb_usbd(&cardp->udev->dev,
				     "Received valid boot command response\n");
			lbtf_deb_leave(LBTF_DEB_USB);
			return;
		}
		if (bcmdresp.magic != cpu_to_le32(BOOT_CMD_MAGIC_NUMBER)) {
			if (bcmdresp.magic == cpu_to_le32(CMD_TYPE_REQUEST) ||
			    bcmdresp.magic == cpu_to_le32(CMD_TYPE_DATA) ||
			    bcmdresp.magic == cpu_to_le32(CMD_TYPE_INDICATION)) {
				if (!cardp->bootcmdresp)
					pr_info("Firmware already seems alive; resetting\n");
				cardp->bootcmdresp = -1;
			} else {
				pr_info("boot cmd response wrong magic number (0x%x)\n",
					    le32_to_cpu(bcmdresp.magic));
			}
		} else if (bcmdresp.cmd != BOOT_CMD_FW_BY_USB) {
			pr_info("boot cmd response cmd_tag error (%d)\n",
				bcmdresp.cmd);
		} else if (bcmdresp.result != BOOT_CMD_RESP_OK) {
			pr_info("boot cmd response result error (%d)\n",
				bcmdresp.result);
		} else {
			cardp->bootcmdresp = 1;
			lbtf_deb_usbd(&cardp->udev->dev,
				"Received valid boot command response\n");
		}

		kfree_skb(skb);
		if_usb_submit_rx_urb_fwload(cardp);
		lbtf_deb_leave(LBTF_DEB_USB);
		return;
	}

	syncfwheader = kmemdup(skb->data, sizeof(struct fwsyncheader),
			       GFP_ATOMIC);
	if (!syncfwheader) {
		lbtf_deb_usbd(&cardp->udev->dev,
			"Failure to allocate syncfwheader\n");
		kfree_skb(skb);
		lbtf_deb_leave(LBTF_DEB_USB);
		return;
	}

	if (!syncfwheader->cmd) {
		lbtf_deb_usb2(&cardp->udev->dev,
			"FW received Blk with correct CRC\n");
		lbtf_deb_usb2(&cardp->udev->dev,
			"FW received Blk seqnum = %d\n",
			le32_to_cpu(syncfwheader->seqnum));
		cardp->CRC_OK = 1;
	} else {
		lbtf_deb_usbd(&cardp->udev->dev,
			"FW received Blk with CRC error\n");
		cardp->CRC_OK = 0;
	}

	kfree_skb(skb);

	/* reschedule timer for 200ms hence */
	mod_timer(&cardp->fw_timeout, jiffies + (HZ/5));

	if (cardp->fwfinalblk) {
		cardp->fwdnldover = 1;
		goto exit;
	}

	if_usb_send_fw_pkt(cardp);

 exit:
	if_usb_submit_rx_urb_fwload(cardp);

	kfree(syncfwheader);

	lbtf_deb_leave(LBTF_DEB_USB);
}

#define MRVDRV_MIN_PKT_LEN	30

static inline void process_cmdtypedata(int recvlength, struct sk_buff *skb,
				       struct if_usb_card *cardp,
				       struct lbtf_private *priv)
{
	if (recvlength > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE + MESSAGE_HEADER_LEN
	    || recvlength < MRVDRV_MIN_PKT_LEN) {
		lbtf_deb_usbd(&cardp->udev->dev, "Packet length is Invalid\n");
		kfree_skb(skb);
		return;
	}

	skb_put(skb, recvlength);
	skb_pull(skb, MESSAGE_HEADER_LEN);
	lbtf_rx(priv, skb);
}

static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff,
				      struct sk_buff *skb,
				      struct if_usb_card *cardp,
				      struct lbtf_private *priv)
{
	if (recvlength > LBS_CMD_BUFFER_SIZE) {
		lbtf_deb_usbd(&cardp->udev->dev,
			     "The receive buffer is too large\n");
		kfree_skb(skb);
		return;
	}

	BUG_ON(!in_interrupt());

	spin_lock(&priv->driver_lock);
	memcpy(priv->cmd_resp_buff, recvbuff + MESSAGE_HEADER_LEN,
	       recvlength - MESSAGE_HEADER_LEN);
	kfree_skb(skb);
	lbtf_cmd_response_rx(priv);
	spin_unlock(&priv->driver_lock);
}

/**
 *  if_usb_receive - read data received from the device.
 *
 *  @urb		pointer to struct urb
 */
static void if_usb_receive(struct urb *urb)
{
	struct if_usb_card *cardp = urb->context;
	struct sk_buff *skb = cardp->rx_skb;
	struct lbtf_private *priv = cardp->priv;
	int recvlength = urb->actual_length;
	uint8_t *recvbuff = NULL;
	uint32_t recvtype = 0;
	__le32 *pkt = (__le32 *) skb->data;

	lbtf_deb_enter(LBTF_DEB_USB);

	if (recvlength) {
		if (urb->status) {
			lbtf_deb_usbd(&cardp->udev->dev, "RX URB failed: %d\n",
				     urb->status);
			kfree_skb(skb);
			goto setup_for_next;
		}

		recvbuff = skb->data;
		recvtype = le32_to_cpu(pkt[0]);
		lbtf_deb_usbd(&cardp->udev->dev,
			    "Recv length = 0x%x, Recv type = 0x%X\n",
			    recvlength, recvtype);
	} else if (urb->status) {
		kfree_skb(skb);
		lbtf_deb_leave(LBTF_DEB_USB);
		return;
	}

	switch (recvtype) {
	case CMD_TYPE_DATA:
		process_cmdtypedata(recvlength, skb, cardp, priv);
		break;

	case CMD_TYPE_REQUEST:
		process_cmdrequest(recvlength, recvbuff, skb, cardp, priv);
		break;

	case CMD_TYPE_INDICATION:
	{
		/* Event cause handling */
		u32 event_cause = le32_to_cpu(pkt[1]);
		lbtf_deb_usbd(&cardp->udev->dev, "**EVENT** 0x%X\n",
			event_cause);

		/* Icky undocumented magic special case */
		if (event_cause & 0xffff0000) {
			u16 tmp;
			u8 retrycnt;
			u8 failure;

			tmp = event_cause >> 16;
			retrycnt = tmp & 0x00ff;
			failure = (tmp & 0xff00) >> 8;
			lbtf_send_tx_feedback(priv, retrycnt, failure);
		} else if (event_cause == LBTF_EVENT_BCN_SENT)
			lbtf_bcn_sent(priv);
		else
			lbtf_deb_usbd(&cardp->udev->dev,
			       "Unsupported notification %d received\n",
			       event_cause);
		kfree_skb(skb);
		break;
	}
	default:
		lbtf_deb_usbd(&cardp->udev->dev,
			"libertastf: unknown command type 0x%X\n", recvtype);
		kfree_skb(skb);
		break;
	}

setup_for_next:
	if_usb_submit_rx_urb(cardp);
	lbtf_deb_leave(LBTF_DEB_USB);
}

/**
 *  if_usb_host_to_card -  Download data to the device
 *
 *  @priv		pointer to struct lbtf_private structure
 *  @type		type of data
 *  @buf		pointer to data buffer
 *  @len		number of bytes
 *
 *  Returns: 0 on success, nonzero otherwise
 */
static int if_usb_host_to_card(struct lbtf_private *priv, uint8_t type,
			       uint8_t *payload, uint16_t nb)
{
	struct if_usb_card *cardp = priv->card;
	u8 data = 0;

	lbtf_deb_usbd(&cardp->udev->dev, "*** type = %u\n", type);
	lbtf_deb_usbd(&cardp->udev->dev, "size after = %d\n", nb);

	if (type == MVMS_CMD) {
		*(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST);
	} else {
		*(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_DATA);
		data = 1;
	}

	memcpy((cardp->ep_out_buf + MESSAGE_HEADER_LEN), payload, nb);

	return usb_tx_block(cardp, cardp->ep_out_buf, nb + MESSAGE_HEADER_LEN,
			    data);
}

/**
 *  if_usb_issue_boot_command - Issue boot command to Boot2.
 *
 *  @ivalue   1 boots from FW by USB-Download, 2 boots from FW in EEPROM.
 *
 *  Returns: 0
 */
static int if_usb_issue_boot_command(struct if_usb_card *cardp, int ivalue)
{
	struct bootcmd *bootcmd = cardp->ep_out_buf;

	/* Prepare command */
	bootcmd->magic = cpu_to_le32(BOOT_CMD_MAGIC_NUMBER);
	bootcmd->cmd = ivalue;
	memset(bootcmd->pad, 0, sizeof(bootcmd->pad));

	/* Issue command */
	usb_tx_block(cardp, cardp->ep_out_buf, sizeof(*bootcmd), 0);

	return 0;
}


/**
 *  check_fwfile_format - Check the validity of Boot2/FW image.
 *
 *  @data	pointer to image
 *  @totlen	image length
 *
 *  Returns: 0 if the image is valid, nonzero otherwise.
 */
static int check_fwfile_format(const u8 *data, u32 totlen)
{
	u32 bincmd, exit;
	u32 blksize, offset, len;
	int ret;

	ret = 1;
	exit = len = 0;

	do {
		struct fwheader *fwh = (void *) data;

		bincmd = le32_to_cpu(fwh->dnldcmd);
		blksize = le32_to_cpu(fwh->datalength);
		switch (bincmd) {
		case FW_HAS_DATA_TO_RECV:
			offset = sizeof(struct fwheader) + blksize;
			data += offset;
			len += offset;
			if (len >= totlen)
				exit = 1;
			break;
		case FW_HAS_LAST_BLOCK:
			exit = 1;
			ret = 0;
			break;
		default:
			exit = 1;
			break;
		}
	} while (!exit);

	if (ret)
		pr_err("firmware file format check FAIL\n");
	else
		lbtf_deb_fw("firmware file format check PASS\n");

	return ret;
}


static int if_usb_prog_firmware(struct if_usb_card *cardp)
{
	int i = 0;
	static int reset_count = 10;
	int ret = 0;

	lbtf_deb_enter(LBTF_DEB_USB);

	kernel_param_lock(THIS_MODULE);
	ret = request_firmware(&cardp->fw, lbtf_fw_name, &cardp->udev->dev);
	if (ret < 0) {
		pr_err("request_firmware() failed with %#x\n", ret);
		pr_err("firmware %s not found\n", lbtf_fw_name);
		kernel_param_unlock(THIS_MODULE);
		goto done;
	}
	kernel_param_unlock(THIS_MODULE);

	if (check_fwfile_format(cardp->fw->data, cardp->fw->size))
		goto release_fw;

restart:
	if (if_usb_submit_rx_urb_fwload(cardp) < 0) {
		lbtf_deb_usbd(&cardp->udev->dev, "URB submission is failed\n");
		ret = -1;
		goto release_fw;
	}

	cardp->bootcmdresp = 0;
	do {
		int j = 0;
		i++;
		/* Issue Boot command = 1, Boot from Download-FW */
		if_usb_issue_boot_command(cardp, BOOT_CMD_FW_BY_USB);
		/* wait for command response */
		do {
			j++;
			msleep_interruptible(100);
		} while (cardp->bootcmdresp == 0 && j < 10);
	} while (cardp->bootcmdresp == 0 && i < 5);

	if (cardp->bootcmdresp <= 0) {
		if (--reset_count >= 0) {
			if_usb_reset_device(cardp);
			goto restart;
		}
		return -1;
	}

	i = 0;

	cardp->totalbytes = 0;
	cardp->fwlastblksent = 0;
	cardp->CRC_OK = 1;
	cardp->fwdnldover = 0;
	cardp->fwseqnum = -1;
	cardp->totalbytes = 0;
	cardp->fwfinalblk = 0;

	/* Send the first firmware packet... */
	if_usb_send_fw_pkt(cardp);

	/* ... and wait for the process to complete */
	wait_event_interruptible(cardp->fw_wq, cardp->priv->surpriseremoved ||
					       cardp->fwdnldover);

	del_timer_sync(&cardp->fw_timeout);
	usb_kill_urb(cardp->rx_urb);

	if (!cardp->fwdnldover) {
		pr_info("failed to load fw, resetting device!\n");
		if (--reset_count >= 0) {
			if_usb_reset_device(cardp);
			goto restart;
		}

		pr_info("FW download failure, time = %d ms\n", i * 100);
		ret = -1;
		goto release_fw;
	}

	cardp->priv->fw_ready = 1;

 release_fw:
	release_firmware(cardp->fw);
	cardp->fw = NULL;

	if_usb_setup_firmware(cardp->priv);

 done:
	lbtf_deb_leave_args(LBTF_DEB_USB, "ret %d", ret);
	return ret;
}


#define if_usb_suspend NULL
#define if_usb_resume NULL

static struct usb_driver if_usb_driver = {
	.name = DRV_NAME,
	.probe = if_usb_probe,
	.disconnect = if_usb_disconnect,
	.id_table = if_usb_table,
	.suspend = if_usb_suspend,
	.resume = if_usb_resume,
	.disable_hub_initiated_lpm = 1,
};

module_usb_driver(if_usb_driver);

MODULE_DESCRIPTION("8388 USB WLAN Thinfirm Driver");
MODULE_AUTHOR("Cozybit Inc.");
MODULE_LICENSE("GPL");
