/*
 * Atheros AR9170 driver
 *
 * USB - frontend
 *
 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
 * Copyright 2009, Christian Lamparter <chunkeey@web.de>
 *
 * 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.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; see the file COPYING.  If not, see
 * http://www.gnu.org/licenses/.
 *
 * This file incorporates work covered by the following copyright and
 * permission notice:
 *    Copyright (c) 2007-2008 Atheros Communications, Inc.
 *
 *    Permission to use, copy, modify, and/or distribute this software for any
 *    purpose with or without fee is hereby granted, provided that the above
 *    copyright notice and this permission notice appear in all copies.
 *
 *    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <linux/module.h>
#include <linux/slab.h>
#include <linux/usb.h>
#include <linux/firmware.h>
#include <linux/etherdevice.h>
#include <linux/device.h>
#include <net/mac80211.h>
#include "ar9170.h"
#include "cmd.h"
#include "hw.h"
#include "usb.h"

MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless");
MODULE_FIRMWARE("ar9170.fw");

enum ar9170_requirements {
	AR9170_REQ_FW1_ONLY = 1,
};

static struct usb_device_id ar9170_usb_ids[] = {
	/* Atheros 9170 */
	{ USB_DEVICE(0x0cf3, 0x9170) },
	/* Atheros TG121N */
	{ USB_DEVICE(0x0cf3, 0x1001) },
	/* TP-Link TL-WN821N v2 */
	{ USB_DEVICE(0x0cf3, 0x1002) },
	/* 3Com Dual Band 802.11n USB Adapter */
	{ USB_DEVICE(0x0cf3, 0x1010) },
	/* H3C Dual Band 802.11n USB Adapter */
	{ USB_DEVICE(0x0cf3, 0x1011) },
	/* Cace Airpcap NX */
	{ USB_DEVICE(0xcace, 0x0300) },
	/* D-Link DWA 160 A1 */
	{ USB_DEVICE(0x07d1, 0x3c10) },
	/* D-Link DWA 160 A2 */
	{ USB_DEVICE(0x07d1, 0x3a09) },
	/* Netgear WNA1000 */
	{ USB_DEVICE(0x0846, 0x9040) },
	/* Netgear WNDA3100 */
	{ USB_DEVICE(0x0846, 0x9010) },
	/* Netgear WN111 v2 */
	{ USB_DEVICE(0x0846, 0x9001) },
	/* Zydas ZD1221 */
	{ USB_DEVICE(0x0ace, 0x1221) },
	/* Proxim ORiNOCO 802.11n USB */
	{ USB_DEVICE(0x1435, 0x0804) },
	/* WNC Generic 11n USB Dongle */
	{ USB_DEVICE(0x1435, 0x0326) },
	/* ZyXEL NWD271N */
	{ USB_DEVICE(0x0586, 0x3417) },
	/* Z-Com UB81 BG */
	{ USB_DEVICE(0x0cde, 0x0023) },
	/* Z-Com UB82 ABG */
	{ USB_DEVICE(0x0cde, 0x0026) },
	/* Sphairon Homelink 1202 */
	{ USB_DEVICE(0x0cde, 0x0027) },
	/* Arcadyan WN7512 */
	{ USB_DEVICE(0x083a, 0xf522) },
	/* Planex GWUS300 */
	{ USB_DEVICE(0x2019, 0x5304) },
	/* IO-Data WNGDNUS2 */
	{ USB_DEVICE(0x04bb, 0x093f) },
	/* AVM FRITZ!WLAN USB Stick N */
	{ USB_DEVICE(0x057C, 0x8401) },
	/* NEC WL300NU-G */
	{ USB_DEVICE(0x0409, 0x0249) },
	/* AVM FRITZ!WLAN USB Stick N 2.4 */
	{ USB_DEVICE(0x057C, 0x8402), .driver_info = AR9170_REQ_FW1_ONLY },
	/* Qwest/Actiontec 802AIN Wireless N USB Network Adapter */
	{ USB_DEVICE(0x1668, 0x1200) },

	/* terminate */
	{}
};
MODULE_DEVICE_TABLE(usb, ar9170_usb_ids);

static void ar9170_usb_submit_urb(struct ar9170_usb *aru)
{
	struct urb *urb;
	unsigned long flags;
	int err;

	if (unlikely(!IS_STARTED(&aru->common)))
		return ;

	spin_lock_irqsave(&aru->tx_urb_lock, flags);
	if (atomic_read(&aru->tx_submitted_urbs) >= AR9170_NUM_TX_URBS) {
		spin_unlock_irqrestore(&aru->tx_urb_lock, flags);
		return ;
	}
	atomic_inc(&aru->tx_submitted_urbs);

	urb = usb_get_from_anchor(&aru->tx_pending);
	if (!urb) {
		atomic_dec(&aru->tx_submitted_urbs);
		spin_unlock_irqrestore(&aru->tx_urb_lock, flags);

		return ;
	}
	spin_unlock_irqrestore(&aru->tx_urb_lock, flags);

	aru->tx_pending_urbs--;
	usb_anchor_urb(urb, &aru->tx_submitted);

	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (unlikely(err)) {
		if (ar9170_nag_limiter(&aru->common))
			dev_err(&aru->udev->dev, "submit_urb failed (%d).\n",
				err);

		usb_unanchor_urb(urb);
		atomic_dec(&aru->tx_submitted_urbs);
		ar9170_tx_callback(&aru->common, urb->context);
	}

	usb_free_urb(urb);
}

static void ar9170_usb_tx_urb_complete_frame(struct urb *urb)
{
	struct sk_buff *skb = urb->context;
	struct ar9170_usb *aru = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));

	if (unlikely(!aru)) {
		dev_kfree_skb_irq(skb);
		return ;
	}

	atomic_dec(&aru->tx_submitted_urbs);

	ar9170_tx_callback(&aru->common, skb);

	ar9170_usb_submit_urb(aru);
}

static void ar9170_usb_tx_urb_complete(struct urb *urb)
{
}

static void ar9170_usb_irq_completed(struct urb *urb)
{
	struct ar9170_usb *aru = urb->context;

	switch (urb->status) {
	/* everything is fine */
	case 0:
		break;

	/* disconnect */
	case -ENOENT:
	case -ECONNRESET:
	case -ENODEV:
	case -ESHUTDOWN:
		goto free;

	default:
		goto resubmit;
	}

	ar9170_handle_command_response(&aru->common, urb->transfer_buffer,
				       urb->actual_length);

resubmit:
	usb_anchor_urb(urb, &aru->rx_submitted);
	if (usb_submit_urb(urb, GFP_ATOMIC)) {
		usb_unanchor_urb(urb);
		goto free;
	}

	return;

free:
	usb_free_coherent(aru->udev, 64, urb->transfer_buffer, urb->transfer_dma);
}

static void ar9170_usb_rx_completed(struct urb *urb)
{
	struct sk_buff *skb = urb->context;
	struct ar9170_usb *aru = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
	int err;

	if (!aru)
		goto free;

	switch (urb->status) {
	/* everything is fine */
	case 0:
		break;

	/* disconnect */
	case -ENOENT:
	case -ECONNRESET:
	case -ENODEV:
	case -ESHUTDOWN:
		goto free;

	default:
		goto resubmit;
	}

	skb_put(skb, urb->actual_length);
	ar9170_rx(&aru->common, skb);

resubmit:
	skb_reset_tail_pointer(skb);
	skb_trim(skb, 0);

	usb_anchor_urb(urb, &aru->rx_submitted);
	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (unlikely(err)) {
		usb_unanchor_urb(urb);
		goto free;
	}

	return ;

free:
	dev_kfree_skb_irq(skb);
}

static int ar9170_usb_prep_rx_urb(struct ar9170_usb *aru,
				  struct urb *urb, gfp_t gfp)
{
	struct sk_buff *skb;

	skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE + 32, gfp);
	if (!skb)
		return -ENOMEM;

	/* reserve some space for mac80211's radiotap */
	skb_reserve(skb, 32);

	usb_fill_bulk_urb(urb, aru->udev,
			  usb_rcvbulkpipe(aru->udev, AR9170_EP_RX),
			  skb->data, min(skb_tailroom(skb),
			  AR9170_MAX_RX_BUFFER_SIZE),
			  ar9170_usb_rx_completed, skb);

	return 0;
}

static int ar9170_usb_alloc_rx_irq_urb(struct ar9170_usb *aru)
{
	struct urb *urb = NULL;
	void *ibuf;
	int err = -ENOMEM;

	/* initialize interrupt endpoint */
	urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!urb)
		goto out;

	ibuf = usb_alloc_coherent(aru->udev, 64, GFP_KERNEL, &urb->transfer_dma);
	if (!ibuf)
		goto out;

	usb_fill_int_urb(urb, aru->udev,
			 usb_rcvintpipe(aru->udev, AR9170_EP_IRQ), ibuf,
			 64, ar9170_usb_irq_completed, aru, 1);
	urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

	usb_anchor_urb(urb, &aru->rx_submitted);
	err = usb_submit_urb(urb, GFP_KERNEL);
	if (err) {
		usb_unanchor_urb(urb);
		usb_free_coherent(aru->udev, 64, urb->transfer_buffer,
				  urb->transfer_dma);
	}

out:
	usb_free_urb(urb);
	return err;
}

static int ar9170_usb_alloc_rx_bulk_urbs(struct ar9170_usb *aru)
{
	struct urb *urb;
	int i;
	int err = -EINVAL;

	for (i = 0; i < AR9170_NUM_RX_URBS; i++) {
		err = -ENOMEM;
		urb = usb_alloc_urb(0, GFP_KERNEL);
		if (!urb)
			goto err_out;

		err = ar9170_usb_prep_rx_urb(aru, urb, GFP_KERNEL);
		if (err) {
			usb_free_urb(urb);
			goto err_out;
		}

		usb_anchor_urb(urb, &aru->rx_submitted);
		err = usb_submit_urb(urb, GFP_KERNEL);
		if (err) {
			usb_unanchor_urb(urb);
			dev_kfree_skb_any((void *) urb->transfer_buffer);
			usb_free_urb(urb);
			goto err_out;
		}
		usb_free_urb(urb);
	}

	/* the device now waiting for a firmware. */
	aru->common.state = AR9170_IDLE;
	return 0;

err_out:

	usb_kill_anchored_urbs(&aru->rx_submitted);
	return err;
}

static int ar9170_usb_flush(struct ar9170 *ar)
{
	struct ar9170_usb *aru = (void *) ar;
	struct urb *urb;
	int ret, err = 0;

	if (IS_STARTED(ar))
		aru->common.state = AR9170_IDLE;

	usb_wait_anchor_empty_timeout(&aru->tx_pending,
					    msecs_to_jiffies(800));
	while ((urb = usb_get_from_anchor(&aru->tx_pending))) {
		ar9170_tx_callback(&aru->common, (void *) urb->context);
		usb_free_urb(urb);
	}

	/* lets wait a while until the tx - queues are dried out */
	ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted,
					    msecs_to_jiffies(100));
	if (ret == 0)
		err = -ETIMEDOUT;

	usb_kill_anchored_urbs(&aru->tx_submitted);

	if (IS_ACCEPTING_CMD(ar))
		aru->common.state = AR9170_STARTED;

	return err;
}

static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru)
{
	int err;

	aru->common.state = AR9170_UNKNOWN_STATE;

	err = ar9170_usb_flush(&aru->common);
	if (err)
		dev_err(&aru->udev->dev, "stuck tx urbs!\n");

	usb_poison_anchored_urbs(&aru->tx_submitted);
	usb_poison_anchored_urbs(&aru->rx_submitted);
}

static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd,
			       unsigned int plen, void *payload,
			       unsigned int outlen, void *out)
{
	struct ar9170_usb *aru = (void *) ar;
	struct urb *urb = NULL;
	unsigned long flags;
	int err = -ENOMEM;

	if (unlikely(!IS_ACCEPTING_CMD(ar)))
		return -EPERM;

	if (WARN_ON(plen > AR9170_MAX_CMD_LEN - 4))
		return -EINVAL;

	urb = usb_alloc_urb(0, GFP_ATOMIC);
	if (unlikely(!urb))
		goto err_free;

	ar->cmdbuf[0] = cpu_to_le32(plen);
	ar->cmdbuf[0] |= cpu_to_le32(cmd << 8);
	/* writing multiple regs fills this buffer already */
	if (plen && payload != (u8 *)(&ar->cmdbuf[1]))
		memcpy(&ar->cmdbuf[1], payload, plen);

	spin_lock_irqsave(&aru->common.cmdlock, flags);
	aru->readbuf = (u8 *)out;
	aru->readlen = outlen;
	spin_unlock_irqrestore(&aru->common.cmdlock, flags);

	usb_fill_int_urb(urb, aru->udev,
			 usb_sndintpipe(aru->udev, AR9170_EP_CMD),
			 aru->common.cmdbuf, plen + 4,
			 ar9170_usb_tx_urb_complete, NULL, 1);

	usb_anchor_urb(urb, &aru->tx_submitted);
	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (unlikely(err)) {
		usb_unanchor_urb(urb);
		usb_free_urb(urb);
		goto err_unbuf;
	}
	usb_free_urb(urb);

	err = wait_for_completion_timeout(&aru->cmd_wait, HZ);
	if (err == 0) {
		err = -ETIMEDOUT;
		goto err_unbuf;
	}

	if (aru->readlen != outlen) {
		err = -EMSGSIZE;
		goto err_unbuf;
	}

	return 0;

err_unbuf:
	/* Maybe the device was removed in the second we were waiting? */
	if (IS_STARTED(ar)) {
		dev_err(&aru->udev->dev, "no command feedback "
					 "received (%d).\n", err);

		/* provide some maybe useful debug information */
		print_hex_dump_bytes("ar9170 cmd: ", DUMP_PREFIX_NONE,
				     aru->common.cmdbuf, plen + 4);
		dump_stack();
	}

	/* invalidate to avoid completing the next prematurely */
	spin_lock_irqsave(&aru->common.cmdlock, flags);
	aru->readbuf = NULL;
	aru->readlen = 0;
	spin_unlock_irqrestore(&aru->common.cmdlock, flags);

err_free:

	return err;
}

static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb)
{
	struct ar9170_usb *aru = (struct ar9170_usb *) ar;
	struct urb *urb;

	if (unlikely(!IS_STARTED(ar))) {
		/* Seriously, what were you drink... err... thinking!? */
		return -EPERM;
	}

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

	usb_fill_bulk_urb(urb, aru->udev,
			  usb_sndbulkpipe(aru->udev, AR9170_EP_TX),
			  skb->data, skb->len,
			  ar9170_usb_tx_urb_complete_frame, skb);
	urb->transfer_flags |= URB_ZERO_PACKET;

	usb_anchor_urb(urb, &aru->tx_pending);
	aru->tx_pending_urbs++;

	usb_free_urb(urb);

	ar9170_usb_submit_urb(aru);
	return 0;
}

static void ar9170_usb_callback_cmd(struct ar9170 *ar, u32 len , void *buffer)
{
	struct ar9170_usb *aru = (void *) ar;
	unsigned long flags;
	u32 in, out;

	if (unlikely(!buffer))
		return ;

	in = le32_to_cpup((__le32 *)buffer);
	out = le32_to_cpu(ar->cmdbuf[0]);

	/* mask off length byte */
	out &= ~0xFF;

	if (aru->readlen >= 0) {
		/* add expected length */
		out |= aru->readlen;
	} else {
		/* add obtained length */
		out |= in & 0xFF;
	}

	/*
	 * Some commands (e.g: AR9170_CMD_FREQUENCY) have a variable response
	 * length and we cannot predict the correct length in advance.
	 * So we only check if we provided enough space for the data.
	 */
	if (unlikely(out < in)) {
		dev_warn(&aru->udev->dev, "received invalid command response "
					  "got %d bytes, instead of %d bytes "
					  "and the resp length is %d bytes\n",
			 in, out, len);
		print_hex_dump_bytes("ar9170 invalid resp: ",
				     DUMP_PREFIX_OFFSET, buffer, len);
		/*
		 * Do not complete, then the command times out,
		 * and we get a stack trace from there.
		 */
		return ;
	}

	spin_lock_irqsave(&aru->common.cmdlock, flags);
	if (aru->readbuf && len > 0) {
		memcpy(aru->readbuf, buffer + 4, len - 4);
		aru->readbuf = NULL;
	}
	complete(&aru->cmd_wait);
	spin_unlock_irqrestore(&aru->common.cmdlock, flags);
}

static int ar9170_usb_upload(struct ar9170_usb *aru, const void *data,
			     size_t len, u32 addr, bool complete)
{
	int transfer, err;
	u8 *buf = kmalloc(4096, GFP_KERNEL);

	if (!buf)
		return -ENOMEM;

	while (len) {
		transfer = min_t(int, len, 4096);
		memcpy(buf, data, transfer);

		err = usb_control_msg(aru->udev, usb_sndctrlpipe(aru->udev, 0),
				      0x30 /* FW DL */, 0x40 | USB_DIR_OUT,
				      addr >> 8, 0, buf, transfer, 1000);

		if (err < 0) {
			kfree(buf);
			return err;
		}

		len -= transfer;
		data += transfer;
		addr += transfer;
	}
	kfree(buf);

	if (complete) {
		err = usb_control_msg(aru->udev, usb_sndctrlpipe(aru->udev, 0),
				      0x31 /* FW DL COMPLETE */,
				      0x40 | USB_DIR_OUT, 0, 0, NULL, 0, 5000);
	}

	return 0;
}

static int ar9170_usb_reset(struct ar9170_usb *aru)
{
	int ret, lock = (aru->intf->condition != USB_INTERFACE_BINDING);

	if (lock) {
		ret = usb_lock_device_for_reset(aru->udev, aru->intf);
		if (ret < 0) {
			dev_err(&aru->udev->dev, "unable to lock device "
				"for reset (%d).\n", ret);
			return ret;
		}
	}

	ret = usb_reset_device(aru->udev);
	if (lock)
		usb_unlock_device(aru->udev);

	/* let it rest - for a second - */
	msleep(1000);

	return ret;
}

static int ar9170_usb_upload_firmware(struct ar9170_usb *aru)
{
	int err;

	if (!aru->init_values)
		goto upload_fw_start;

	/* First, upload initial values to device RAM */
	err = ar9170_usb_upload(aru, aru->init_values->data,
				aru->init_values->size, 0x102800, false);
	if (err) {
		dev_err(&aru->udev->dev, "firmware part 1 "
			"upload failed (%d).\n", err);
		return err;
	}

upload_fw_start:

	/* Then, upload the firmware itself and start it */
	return ar9170_usb_upload(aru, aru->firmware->data, aru->firmware->size,
				0x200000, true);
}

static int ar9170_usb_init_transport(struct ar9170_usb *aru)
{
	struct ar9170 *ar = (void *) &aru->common;
	int err;

	ar9170_regwrite_begin(ar);

	/* Set USB Rx stream mode MAX packet number to 2 */
	ar9170_regwrite(AR9170_USB_REG_MAX_AGG_UPLOAD, 0x4);

	/* Set USB Rx stream mode timeout to 10us */
	ar9170_regwrite(AR9170_USB_REG_UPLOAD_TIME_CTL, 0x80);

	ar9170_regwrite_finish();

	err = ar9170_regwrite_result();
	if (err)
		dev_err(&aru->udev->dev, "USB setup failed (%d).\n", err);

	return err;
}

static void ar9170_usb_stop(struct ar9170 *ar)
{
	struct ar9170_usb *aru = (void *) ar;
	int ret;

	if (IS_ACCEPTING_CMD(ar))
		aru->common.state = AR9170_STOPPED;

	ret = ar9170_usb_flush(ar);
	if (ret)
		dev_err(&aru->udev->dev, "kill pending tx urbs.\n");

	usb_poison_anchored_urbs(&aru->tx_submitted);

	/*
	 * Note:
	 * So far we freed all tx urbs, but we won't dare to touch any rx urbs.
	 * Else we would end up with a unresponsive device...
	 */
}

static int ar9170_usb_open(struct ar9170 *ar)
{
	struct ar9170_usb *aru = (void *) ar;
	int err;

	usb_unpoison_anchored_urbs(&aru->tx_submitted);
	err = ar9170_usb_init_transport(aru);
	if (err) {
		usb_poison_anchored_urbs(&aru->tx_submitted);
		return err;
	}

	aru->common.state = AR9170_IDLE;
	return 0;
}

static int ar9170_usb_init_device(struct ar9170_usb *aru)
{
	int err;

	err = ar9170_usb_alloc_rx_irq_urb(aru);
	if (err)
		goto err_out;

	err = ar9170_usb_alloc_rx_bulk_urbs(aru);
	if (err)
		goto err_unrx;

	err = ar9170_usb_upload_firmware(aru);
	if (err) {
		err = ar9170_echo_test(&aru->common, 0x60d43110);
		if (err) {
			/* force user invention, by disabling the device */
			err = usb_driver_set_configuration(aru->udev, -1);
			dev_err(&aru->udev->dev, "device is in a bad state. "
						 "please reconnect it!\n");
			goto err_unrx;
		}
	}

	return 0;

err_unrx:
	ar9170_usb_cancel_urbs(aru);

err_out:
	return err;
}

static void ar9170_usb_firmware_failed(struct ar9170_usb *aru)
{
	struct device *parent = aru->udev->dev.parent;
	struct usb_device *udev;

	/*
	 * Store a copy of the usb_device pointer locally.
	 * This is because device_release_driver initiates
	 * ar9170_usb_disconnect, which in turn frees our
	 * driver context (aru).
	 */
	udev = aru->udev;

	complete(&aru->firmware_loading_complete);

	/* unbind anything failed */
	if (parent)
		device_lock(parent);

	device_release_driver(&udev->dev);
	if (parent)
		device_unlock(parent);

	usb_put_dev(udev);
}

static void ar9170_usb_firmware_finish(const struct firmware *fw, void *context)
{
	struct ar9170_usb *aru = context;
	int err;

	aru->firmware = fw;

	if (!fw) {
		dev_err(&aru->udev->dev, "firmware file not found.\n");
		goto err_freefw;
	}

	err = ar9170_usb_init_device(aru);
	if (err)
		goto err_freefw;

	err = ar9170_usb_open(&aru->common);
	if (err)
		goto err_unrx;

	err = ar9170_register(&aru->common, &aru->udev->dev);

	ar9170_usb_stop(&aru->common);
	if (err)
		goto err_unrx;

	complete(&aru->firmware_loading_complete);
	usb_put_dev(aru->udev);
	return;

 err_unrx:
	ar9170_usb_cancel_urbs(aru);

 err_freefw:
	ar9170_usb_firmware_failed(aru);
}

static void ar9170_usb_firmware_inits(const struct firmware *fw,
				      void *context)
{
	struct ar9170_usb *aru = context;
	int err;

	if (!fw) {
		dev_err(&aru->udev->dev, "file with init values not found.\n");
		ar9170_usb_firmware_failed(aru);
		return;
	}

	aru->init_values = fw;

	/* ok so we have the init values -- get code for two-stage */

	err = request_firmware_nowait(THIS_MODULE, 1, "ar9170-2.fw",
				      &aru->udev->dev, GFP_KERNEL, aru,
				      ar9170_usb_firmware_finish);
	if (err)
		ar9170_usb_firmware_failed(aru);
}

static void ar9170_usb_firmware_step2(const struct firmware *fw, void *context)
{
	struct ar9170_usb *aru = context;
	int err;

	if (fw) {
		ar9170_usb_firmware_finish(fw, context);
		return;
	}

	if (aru->req_one_stage_fw) {
		dev_err(&aru->udev->dev, "ar9170.fw firmware file "
			"not found and is required for this device\n");
		ar9170_usb_firmware_failed(aru);
		return;
	}

	dev_err(&aru->udev->dev, "ar9170.fw firmware file "
		"not found, trying old firmware...\n");

	err = request_firmware_nowait(THIS_MODULE, 1, "ar9170-1.fw",
				      &aru->udev->dev, GFP_KERNEL, aru,
				      ar9170_usb_firmware_inits);
	if (err)
		ar9170_usb_firmware_failed(aru);
}

static bool ar9170_requires_one_stage(const struct usb_device_id *id)
{
	if (!id->driver_info)
		return false;
	if (id->driver_info == AR9170_REQ_FW1_ONLY)
		return true;
	return false;
}

static int ar9170_usb_probe(struct usb_interface *intf,
			const struct usb_device_id *id)
{
	struct ar9170_usb *aru;
	struct ar9170 *ar;
	struct usb_device *udev;
	int err;

	aru = ar9170_alloc(sizeof(*aru));
	if (IS_ERR(aru)) {
		err = PTR_ERR(aru);
		goto out;
	}

	udev = interface_to_usbdev(intf);
	usb_get_dev(udev);
	aru->udev = udev;
	aru->intf = intf;
	ar = &aru->common;

	aru->req_one_stage_fw = ar9170_requires_one_stage(id);

	usb_set_intfdata(intf, aru);
	SET_IEEE80211_DEV(ar->hw, &intf->dev);

	init_usb_anchor(&aru->rx_submitted);
	init_usb_anchor(&aru->tx_pending);
	init_usb_anchor(&aru->tx_submitted);
	init_completion(&aru->cmd_wait);
	init_completion(&aru->firmware_loading_complete);
	spin_lock_init(&aru->tx_urb_lock);

	aru->tx_pending_urbs = 0;
	atomic_set(&aru->tx_submitted_urbs, 0);

	aru->common.stop = ar9170_usb_stop;
	aru->common.flush = ar9170_usb_flush;
	aru->common.open = ar9170_usb_open;
	aru->common.tx = ar9170_usb_tx;
	aru->common.exec_cmd = ar9170_usb_exec_cmd;
	aru->common.callback_cmd = ar9170_usb_callback_cmd;

#ifdef CONFIG_PM
	udev->reset_resume = 1;
#endif /* CONFIG_PM */
	err = ar9170_usb_reset(aru);
	if (err)
		goto err_freehw;

	usb_get_dev(aru->udev);
	return request_firmware_nowait(THIS_MODULE, 1, "ar9170.fw",
				       &aru->udev->dev, GFP_KERNEL, aru,
				       ar9170_usb_firmware_step2);
err_freehw:
	usb_set_intfdata(intf, NULL);
	usb_put_dev(udev);
	ieee80211_free_hw(ar->hw);
out:
	return err;
}

static void ar9170_usb_disconnect(struct usb_interface *intf)
{
	struct ar9170_usb *aru = usb_get_intfdata(intf);

	if (!aru)
		return;

	aru->common.state = AR9170_IDLE;

	wait_for_completion(&aru->firmware_loading_complete);

	ar9170_unregister(&aru->common);
	ar9170_usb_cancel_urbs(aru);

	usb_put_dev(aru->udev);
	usb_set_intfdata(intf, NULL);
	ieee80211_free_hw(aru->common.hw);

	release_firmware(aru->init_values);
	release_firmware(aru->firmware);
}

#ifdef CONFIG_PM
static int ar9170_suspend(struct usb_interface *intf,
			  pm_message_t  message)
{
	struct ar9170_usb *aru = usb_get_intfdata(intf);

	if (!aru)
		return -ENODEV;

	aru->common.state = AR9170_IDLE;
	ar9170_usb_cancel_urbs(aru);

	return 0;
}

static int ar9170_resume(struct usb_interface *intf)
{
	struct ar9170_usb *aru = usb_get_intfdata(intf);
	int err;

	if (!aru)
		return -ENODEV;

	usb_unpoison_anchored_urbs(&aru->rx_submitted);
	usb_unpoison_anchored_urbs(&aru->tx_submitted);

	err = ar9170_usb_init_device(aru);
	if (err)
		goto err_unrx;

	err = ar9170_usb_open(&aru->common);
	if (err)
		goto err_unrx;

	return 0;

err_unrx:
	aru->common.state = AR9170_IDLE;
	ar9170_usb_cancel_urbs(aru);

	return err;
}
#endif /* CONFIG_PM */

static struct usb_driver ar9170_driver = {
	.name = "ar9170usb",
	.probe = ar9170_usb_probe,
	.disconnect = ar9170_usb_disconnect,
	.id_table = ar9170_usb_ids,
	.soft_unbind = 1,
#ifdef CONFIG_PM
	.suspend = ar9170_suspend,
	.resume = ar9170_resume,
	.reset_resume = ar9170_resume,
#endif /* CONFIG_PM */
};

static int __init ar9170_init(void)
{
	return usb_register(&ar9170_driver);
}

static void __exit ar9170_exit(void)
{
	usb_deregister(&ar9170_driver);
}

module_init(ar9170_init);
module_exit(ar9170_exit);
