// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2021 pureLiFi
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/usb.h>
#include <linux/workqueue.h>
#include <linux/proc_fs.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/module.h>
#include <net/mac80211.h>
#include <asm/unaligned.h>
#include <linux/sysfs.h>

#include "mac.h"
#include "usb.h"
#include "chip.h"

static const struct usb_device_id usb_ids[] = {
	{ USB_DEVICE(PURELIFI_X_VENDOR_ID_0, PURELIFI_X_PRODUCT_ID_0),
	  .driver_info = DEVICE_LIFI_X },
	{ USB_DEVICE(PURELIFI_XC_VENDOR_ID_0, PURELIFI_XC_PRODUCT_ID_0),
	  .driver_info = DEVICE_LIFI_XC },
	{ USB_DEVICE(PURELIFI_XL_VENDOR_ID_0, PURELIFI_XL_PRODUCT_ID_0),
	  .driver_info = DEVICE_LIFI_XL },
	{}
};

void plfxlc_send_packet_from_data_queue(struct plfxlc_usb *usb)
{
	struct plfxlc_usb_tx *tx = &usb->tx;
	struct sk_buff *skb = NULL;
	unsigned long flags;
	u8 last_served_sidx;

	spin_lock_irqsave(&tx->lock, flags);
	last_served_sidx = usb->sidx;
	do {
		usb->sidx = (usb->sidx + 1) % MAX_STA_NUM;
		if (!(tx->station[usb->sidx].flag & STATION_CONNECTED_FLAG))
			continue;
		if (!(tx->station[usb->sidx].flag & STATION_FIFO_FULL_FLAG))
			skb = skb_peek(&tx->station[usb->sidx].data_list);
	} while ((usb->sidx != last_served_sidx) && (!skb));

	if (skb) {
		skb = skb_dequeue(&tx->station[usb->sidx].data_list);
		plfxlc_usb_wreq_async(usb, skb->data, skb->len, USB_REQ_DATA_TX,
				      plfxlc_tx_urb_complete, skb);
		if (skb_queue_len(&tx->station[usb->sidx].data_list) <= 60)
			ieee80211_wake_queues(plfxlc_usb_to_hw(usb));
	}
	spin_unlock_irqrestore(&tx->lock, flags);
}

static void handle_rx_packet(struct plfxlc_usb *usb, const u8 *buffer,
			     unsigned int length)
{
	plfxlc_mac_rx(plfxlc_usb_to_hw(usb), buffer, length);
}

static void rx_urb_complete(struct urb *urb)
{
	struct plfxlc_usb_tx *tx;
	struct plfxlc_usb *usb;
	unsigned int length;
	const u8 *buffer;
	u16 status;
	u8 sidx;
	int r;

	if (!urb) {
		pr_err("urb is NULL\n");
		return;
	}
	if (!urb->context) {
		pr_err("urb ctx is NULL\n");
		return;
	}
	usb = urb->context;

	if (usb->initialized != 1) {
		pr_err("usb is not initialized\n");
		return;
	}

	tx = &usb->tx;
	switch (urb->status) {
	case 0:
		break;
	case -ESHUTDOWN:
	case -EINVAL:
	case -ENODEV:
	case -ENOENT:
	case -ECONNRESET:
	case -EPIPE:
		dev_dbg(plfxlc_urb_dev(urb), "urb %p error %d\n", urb, urb->status);
		return;
	default:
		dev_dbg(plfxlc_urb_dev(urb), "urb %p error %d\n", urb, urb->status);
		if (tx->submitted_urbs++ < PURELIFI_URB_RETRY_MAX) {
			dev_dbg(plfxlc_urb_dev(urb), "urb %p resubmit %d", urb,
				tx->submitted_urbs++);
			goto resubmit;
		} else {
			dev_dbg(plfxlc_urb_dev(urb), "urb %p  max resubmits reached", urb);
			tx->submitted_urbs = 0;
			return;
		}
	}

	buffer = urb->transfer_buffer;
	length = le32_to_cpu(*(__le32 *)(buffer + sizeof(struct rx_status)))
		 + sizeof(u32);

	if (urb->actual_length != (PLF_MSG_STATUS_OFFSET + 1)) {
		if (usb->initialized && usb->link_up)
			handle_rx_packet(usb, buffer, length);
		goto resubmit;
	}

	status = buffer[PLF_MSG_STATUS_OFFSET];

	switch (status) {
	case STATION_FIFO_ALMOST_FULL_NOT_MESSAGE:
		dev_dbg(&usb->intf->dev,
			"FIFO full not packet receipt\n");
		tx->mac_fifo_full = 1;
		for (sidx = 0; sidx < MAX_STA_NUM; sidx++)
			tx->station[sidx].flag |= STATION_FIFO_FULL_FLAG;
		break;
	case STATION_FIFO_ALMOST_FULL_MESSAGE:
		dev_dbg(&usb->intf->dev, "FIFO full packet receipt\n");

		for (sidx = 0; sidx < MAX_STA_NUM; sidx++)
			tx->station[sidx].flag &= STATION_ACTIVE_FLAG;

		plfxlc_send_packet_from_data_queue(usb);
		break;
	case STATION_CONNECT_MESSAGE:
		usb->link_up = 1;
		dev_dbg(&usb->intf->dev, "ST_CONNECT_MSG packet receipt\n");
		break;
	case STATION_DISCONNECT_MESSAGE:
		usb->link_up = 0;
		dev_dbg(&usb->intf->dev, "ST_DISCONN_MSG packet receipt\n");
		break;
	default:
		dev_dbg(&usb->intf->dev, "Unknown packet receipt\n");
		break;
	}

resubmit:
	r = usb_submit_urb(urb, GFP_ATOMIC);
	if (r)
		dev_dbg(plfxlc_urb_dev(urb), "urb %p resubmit fail (%d)\n", urb, r);
}

static struct urb *alloc_rx_urb(struct plfxlc_usb *usb)
{
	struct usb_device *udev = plfxlc_usb_to_usbdev(usb);
	struct urb *urb;
	void *buffer;

	urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!urb)
		return NULL;

	buffer = usb_alloc_coherent(udev, USB_MAX_RX_SIZE, GFP_KERNEL,
				    &urb->transfer_dma);
	if (!buffer) {
		usb_free_urb(urb);
		return NULL;
	}

	usb_fill_bulk_urb(urb, udev, usb_rcvbulkpipe(udev, EP_DATA_IN),
			  buffer, USB_MAX_RX_SIZE,
			  rx_urb_complete, usb);
	urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

	return urb;
}

static void free_rx_urb(struct urb *urb)
{
	if (!urb)
		return;
	usb_free_coherent(urb->dev, urb->transfer_buffer_length,
			  urb->transfer_buffer, urb->transfer_dma);
	usb_free_urb(urb);
}

static int __lf_x_usb_enable_rx(struct plfxlc_usb *usb)
{
	struct plfxlc_usb_rx *rx = &usb->rx;
	struct urb **urbs;
	int i, r;

	r = -ENOMEM;
	urbs = kcalloc(RX_URBS_COUNT, sizeof(struct urb *), GFP_KERNEL);
	if (!urbs)
		goto error;

	for (i = 0; i < RX_URBS_COUNT; i++) {
		urbs[i] = alloc_rx_urb(usb);
		if (!urbs[i])
			goto error;
	}

	spin_lock_irq(&rx->lock);

	dev_dbg(plfxlc_usb_dev(usb), "irq_disabled %d\n", irqs_disabled());

	if (rx->urbs) {
		spin_unlock_irq(&rx->lock);
		r = 0;
		goto error;
	}
	rx->urbs = urbs;
	rx->urbs_count = RX_URBS_COUNT;
	spin_unlock_irq(&rx->lock);

	for (i = 0; i < RX_URBS_COUNT; i++) {
		r = usb_submit_urb(urbs[i], GFP_KERNEL);
		if (r)
			goto error_submit;
	}

	return 0;

error_submit:
	for (i = 0; i < RX_URBS_COUNT; i++)
		usb_kill_urb(urbs[i]);
	spin_lock_irq(&rx->lock);
	rx->urbs = NULL;
	rx->urbs_count = 0;
	spin_unlock_irq(&rx->lock);
error:
	if (urbs) {
		for (i = 0; i < RX_URBS_COUNT; i++)
			free_rx_urb(urbs[i]);
	}
	kfree(urbs);
	return r;
}

int plfxlc_usb_enable_rx(struct plfxlc_usb *usb)
{
	struct plfxlc_usb_rx *rx = &usb->rx;
	int r;

	mutex_lock(&rx->setup_mutex);
	r = __lf_x_usb_enable_rx(usb);
	if (!r)
		usb->rx_usb_enabled = 1;

	mutex_unlock(&rx->setup_mutex);

	return r;
}

static void __lf_x_usb_disable_rx(struct plfxlc_usb *usb)
{
	struct plfxlc_usb_rx *rx = &usb->rx;
	unsigned long flags;
	unsigned int count;
	struct urb **urbs;
	int i;

	spin_lock_irqsave(&rx->lock, flags);
	urbs = rx->urbs;
	count = rx->urbs_count;
	spin_unlock_irqrestore(&rx->lock, flags);

	if (!urbs)
		return;

	for (i = 0; i < count; i++) {
		usb_kill_urb(urbs[i]);
		free_rx_urb(urbs[i]);
	}
	kfree(urbs);
	rx->urbs = NULL;
	rx->urbs_count = 0;
}

void plfxlc_usb_disable_rx(struct plfxlc_usb *usb)
{
	struct plfxlc_usb_rx *rx = &usb->rx;

	mutex_lock(&rx->setup_mutex);
	__lf_x_usb_disable_rx(usb);
	usb->rx_usb_enabled = 0;
	mutex_unlock(&rx->setup_mutex);
}

void plfxlc_usb_disable_tx(struct plfxlc_usb *usb)
{
	struct plfxlc_usb_tx *tx = &usb->tx;
	unsigned long flags;

	clear_bit(PLF_BIT_ENABLED, &tx->enabled);

	/* kill all submitted tx-urbs */
	usb_kill_anchored_urbs(&tx->submitted);

	spin_lock_irqsave(&tx->lock, flags);
	WARN_ON(!skb_queue_empty(&tx->submitted_skbs));
	WARN_ON(tx->submitted_urbs != 0);
	tx->submitted_urbs = 0;
	spin_unlock_irqrestore(&tx->lock, flags);

	/* The stopped state is ignored, relying on ieee80211_wake_queues()
	 * in a potentionally following plfxlc_usb_enable_tx().
	 */
}

void plfxlc_usb_enable_tx(struct plfxlc_usb *usb)
{
	struct plfxlc_usb_tx *tx = &usb->tx;
	unsigned long flags;

	spin_lock_irqsave(&tx->lock, flags);
	set_bit(PLF_BIT_ENABLED, &tx->enabled);
	tx->submitted_urbs = 0;
	ieee80211_wake_queues(plfxlc_usb_to_hw(usb));
	tx->stopped = 0;
	spin_unlock_irqrestore(&tx->lock, flags);
}

void plfxlc_tx_urb_complete(struct urb *urb)
{
	struct ieee80211_tx_info *info;
	struct plfxlc_usb *usb;
	struct sk_buff *skb;

	skb = urb->context;
	info = IEEE80211_SKB_CB(skb);
	/* grab 'usb' pointer before handing off the skb (since
	 * it might be freed by plfxlc_mac_tx_to_dev or mac80211)
	 */
	usb = &plfxlc_hw_mac(info->rate_driver_data[0])->chip.usb;

	switch (urb->status) {
	case 0:
		break;
	case -ESHUTDOWN:
	case -EINVAL:
	case -ENODEV:
	case -ENOENT:
	case -ECONNRESET:
	case -EPIPE:
		dev_dbg(plfxlc_urb_dev(urb), "urb %p error %d\n", urb, urb->status);
		break;
	default:
		dev_dbg(plfxlc_urb_dev(urb), "urb %p error %d\n", urb, urb->status);
		return;
	}

	plfxlc_mac_tx_to_dev(skb, urb->status);
	plfxlc_send_packet_from_data_queue(usb);
	usb_free_urb(urb);
}

static inline void init_usb_rx(struct plfxlc_usb *usb)
{
	struct plfxlc_usb_rx *rx = &usb->rx;

	spin_lock_init(&rx->lock);
	mutex_init(&rx->setup_mutex);

	if (interface_to_usbdev(usb->intf)->speed == USB_SPEED_HIGH)
		rx->usb_packet_size = 512;
	else
		rx->usb_packet_size = 64;

	if (rx->fragment_length != 0)
		dev_dbg(plfxlc_usb_dev(usb), "fragment_length error\n");
}

static inline void init_usb_tx(struct plfxlc_usb *usb)
{
	struct plfxlc_usb_tx *tx = &usb->tx;

	spin_lock_init(&tx->lock);
	clear_bit(PLF_BIT_ENABLED, &tx->enabled);
	tx->stopped = 0;
	skb_queue_head_init(&tx->submitted_skbs);
	init_usb_anchor(&tx->submitted);
}

void plfxlc_usb_init(struct plfxlc_usb *usb, struct ieee80211_hw *hw,
		     struct usb_interface *intf)
{
	memset(usb, 0, sizeof(*usb));
	usb->intf = usb_get_intf(intf);
	usb_set_intfdata(usb->intf, hw);
	init_usb_tx(usb);
	init_usb_rx(usb);
}

void plfxlc_usb_release(struct plfxlc_usb *usb)
{
	plfxlc_op_stop(plfxlc_usb_to_hw(usb));
	plfxlc_usb_disable_tx(usb);
	plfxlc_usb_disable_rx(usb);
	usb_set_intfdata(usb->intf, NULL);
	usb_put_intf(usb->intf);
}

const char *plfxlc_speed(enum usb_device_speed speed)
{
	switch (speed) {
	case USB_SPEED_LOW:
		return "low";
	case USB_SPEED_FULL:
		return "full";
	case USB_SPEED_HIGH:
		return "high";
	default:
		return "unknown";
	}
}

int plfxlc_usb_init_hw(struct plfxlc_usb *usb)
{
	int r;

	r = usb_reset_configuration(plfxlc_usb_to_usbdev(usb));
	if (r) {
		dev_err(plfxlc_usb_dev(usb), "cfg reset failed (%d)\n", r);
		return r;
	}
	return 0;
}

static void get_usb_req(struct usb_device *udev, void *buffer,
			u32 buffer_len, enum plf_usb_req_enum usb_req_id,
			struct plf_usb_req *usb_req)
{
	__be32 payload_len_nw = cpu_to_be32(buffer_len + FCS_LEN);
	const u8 *buffer_src_p = buffer;
	u8 *buffer_dst = usb_req->buf;
	u32 temp_usb_len = 0;

	usb_req->id = cpu_to_be32(usb_req_id);
	usb_req->len  = cpu_to_be32(0);

	/* Copy buffer length into the transmitted buffer, as it is important
	 * for the Rx MAC to know its exact length.
	 */
	if (usb_req->id == cpu_to_be32(USB_REQ_BEACON_WR)) {
		memcpy(buffer_dst, &payload_len_nw, sizeof(payload_len_nw));
		buffer_dst += sizeof(payload_len_nw);
		temp_usb_len += sizeof(payload_len_nw);
	}

	memcpy(buffer_dst, buffer_src_p, buffer_len);
	buffer_dst += buffer_len;
	buffer_src_p += buffer_len;
	temp_usb_len +=  buffer_len;

	/* Set the FCS_LEN (4) bytes as 0 for CRC checking. */
	memset(buffer_dst, 0, FCS_LEN);
	buffer_dst += FCS_LEN;
	temp_usb_len += FCS_LEN;

	/* Round the packet to be transmitted to 4 bytes. */
	if (temp_usb_len % PURELIFI_BYTE_NUM_ALIGNMENT) {
		memset(buffer_dst, 0, PURELIFI_BYTE_NUM_ALIGNMENT -
		       (temp_usb_len %
			PURELIFI_BYTE_NUM_ALIGNMENT));
		buffer_dst += PURELIFI_BYTE_NUM_ALIGNMENT -
				(temp_usb_len %
				PURELIFI_BYTE_NUM_ALIGNMENT);
		temp_usb_len += PURELIFI_BYTE_NUM_ALIGNMENT -
				(temp_usb_len % PURELIFI_BYTE_NUM_ALIGNMENT);
	}

	usb_req->len = cpu_to_be32(temp_usb_len);
}

int plfxlc_usb_wreq_async(struct plfxlc_usb *usb, const u8 *buffer,
			  int buffer_len, enum plf_usb_req_enum usb_req_id,
			  usb_complete_t complete_fn,
			  void *context)
{
	struct usb_device *udev = interface_to_usbdev(usb->ez_usb);
	struct urb *urb = usb_alloc_urb(0, GFP_ATOMIC);
	int r;

	usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, EP_DATA_OUT),
			  (void *)buffer, buffer_len, complete_fn, context);

	r = usb_submit_urb(urb, GFP_ATOMIC);
	if (r)
		dev_err(&udev->dev, "Async write submit failed (%d)\n", r);

	return r;
}

int plfxlc_usb_wreq(struct usb_interface *ez_usb, void *buffer, int buffer_len,
		    enum plf_usb_req_enum usb_req_id)
{
	struct usb_device *udev = interface_to_usbdev(ez_usb);
	unsigned char *dma_buffer = NULL;
	struct plf_usb_req usb_req;
	int usb_bulk_msg_len;
	int actual_length;
	int r;

	get_usb_req(udev, buffer, buffer_len, usb_req_id, &usb_req);
	usb_bulk_msg_len = sizeof(__le32) + sizeof(__le32) +
			   be32_to_cpu(usb_req.len);

	dma_buffer = kmemdup(&usb_req, usb_bulk_msg_len, GFP_KERNEL);

	if (!dma_buffer) {
		r = -ENOMEM;
		goto error;
	}

	r = usb_bulk_msg(udev,
			 usb_sndbulkpipe(udev, EP_DATA_OUT),
			 dma_buffer, usb_bulk_msg_len,
			 &actual_length, USB_BULK_MSG_TIMEOUT_MS);
	kfree(dma_buffer);
error:
	if (r) {
		r = -ENOMEM;
		dev_err(&udev->dev, "usb_bulk_msg failed (%d)\n", r);
	}

	return r;
}

static void slif_data_plane_sap_timer_callb(struct timer_list *t)
{
	struct plfxlc_usb *usb = from_timer(usb, t, tx.tx_retry_timer);

	plfxlc_send_packet_from_data_queue(usb);
	timer_setup(&usb->tx.tx_retry_timer,
		    slif_data_plane_sap_timer_callb, 0);
	mod_timer(&usb->tx.tx_retry_timer, jiffies + TX_RETRY_BACKOFF_JIFF);
}

static void sta_queue_cleanup_timer_callb(struct timer_list *t)
{
	struct plfxlc_usb *usb = from_timer(usb, t, sta_queue_cleanup);
	struct plfxlc_usb_tx *tx = &usb->tx;
	int sidx;

	for (sidx = 0; sidx < MAX_STA_NUM - 1; sidx++) {
		if (!(tx->station[sidx].flag & STATION_CONNECTED_FLAG))
			continue;
		if (tx->station[sidx].flag & STATION_HEARTBEAT_FLAG) {
			tx->station[sidx].flag ^= STATION_HEARTBEAT_FLAG;
		} else {
			eth_zero_addr(tx->station[sidx].mac);
			tx->station[sidx].flag = 0;
		}
	}
	timer_setup(&usb->sta_queue_cleanup,
		    sta_queue_cleanup_timer_callb, 0);
	mod_timer(&usb->sta_queue_cleanup, jiffies + STA_QUEUE_CLEANUP_JIFF);
}

static int probe(struct usb_interface *intf,
		 const struct usb_device_id *id)
{
	u8 serial_number[PURELIFI_SERIAL_LEN];
	struct ieee80211_hw *hw = NULL;
	struct plfxlc_usb_tx *tx;
	struct plfxlc_chip *chip;
	struct plfxlc_usb *usb;
	u8 hw_address[ETH_ALEN];
	unsigned int i;
	int r = 0;

	hw = plfxlc_mac_alloc_hw(intf);

	if (!hw) {
		r = -ENOMEM;
		goto error;
	}

	chip = &plfxlc_hw_mac(hw)->chip;
	usb = &chip->usb;
	usb->ez_usb = intf;
	tx = &usb->tx;

	r = plfxlc_upload_mac_and_serial(intf, hw_address, serial_number);
	if (r) {
		dev_err(&intf->dev, "MAC and Serial upload failed (%d)\n", r);
		goto error;
	}

	chip->unit_type = STA;
	dev_err(&intf->dev, "Unit type is station");

	r = plfxlc_mac_preinit_hw(hw, hw_address);
	if (r) {
		dev_err(&intf->dev, "Init mac failed (%d)\n", r);
		goto error;
	}

	r = ieee80211_register_hw(hw);
	if (r) {
		dev_err(&intf->dev, "Register device failed (%d)\n", r);
		goto error;
	}

	if ((le16_to_cpu(interface_to_usbdev(intf)->descriptor.idVendor) ==
				PURELIFI_XL_VENDOR_ID_0) &&
	    (le16_to_cpu(interface_to_usbdev(intf)->descriptor.idProduct) ==
				PURELIFI_XL_PRODUCT_ID_0)) {
		r = plfxlc_download_xl_firmware(intf);
	} else {
		r = plfxlc_download_fpga(intf);
	}
	if (r != 0) {
		dev_err(&intf->dev, "FPGA download failed (%d)\n", r);
		goto error;
	}

	tx->mac_fifo_full = 0;
	spin_lock_init(&tx->lock);

	msleep(PLF_MSLEEP_TIME);
	r = plfxlc_usb_init_hw(usb);
	if (r < 0) {
		dev_err(&intf->dev, "usb_init_hw failed (%d)\n", r);
		goto error;
	}

	msleep(PLF_MSLEEP_TIME);
	r = plfxlc_chip_switch_radio(chip, PLFXLC_RADIO_ON);
	if (r < 0) {
		dev_dbg(&intf->dev, "chip_switch_radio_on failed (%d)\n", r);
		goto error;
	}

	msleep(PLF_MSLEEP_TIME);
	r = plfxlc_chip_set_rate(chip, 8);
	if (r < 0) {
		dev_dbg(&intf->dev, "chip_set_rate failed (%d)\n", r);
		goto error;
	}

	msleep(PLF_MSLEEP_TIME);
	r = plfxlc_usb_wreq(usb->ez_usb,
			    hw_address, ETH_ALEN, USB_REQ_MAC_WR);
	if (r < 0) {
		dev_dbg(&intf->dev, "MAC_WR failure (%d)\n", r);
		goto error;
	}

	plfxlc_chip_enable_rxtx(chip);

	/* Initialise the data plane Tx queue */
	for (i = 0; i < MAX_STA_NUM; i++) {
		skb_queue_head_init(&tx->station[i].data_list);
		tx->station[i].flag = 0;
	}

	tx->station[STA_BROADCAST_INDEX].flag |= STATION_CONNECTED_FLAG;
	for (i = 0; i < ETH_ALEN; i++)
		tx->station[STA_BROADCAST_INDEX].mac[i] = 0xFF;

	timer_setup(&tx->tx_retry_timer, slif_data_plane_sap_timer_callb, 0);
	tx->tx_retry_timer.expires = jiffies + TX_RETRY_BACKOFF_JIFF;
	add_timer(&tx->tx_retry_timer);

	timer_setup(&usb->sta_queue_cleanup,
		    sta_queue_cleanup_timer_callb, 0);
	usb->sta_queue_cleanup.expires = jiffies + STA_QUEUE_CLEANUP_JIFF;
	add_timer(&usb->sta_queue_cleanup);

	plfxlc_mac_init_hw(hw);
	usb->initialized = true;
	return 0;
error:
	if (hw) {
		plfxlc_mac_release(plfxlc_hw_mac(hw));
		ieee80211_unregister_hw(hw);
		ieee80211_free_hw(hw);
	}
	dev_err(&intf->dev, "pureLifi:Device error");
	return r;
}

static void disconnect(struct usb_interface *intf)
{
	struct ieee80211_hw *hw = plfxlc_intf_to_hw(intf);
	struct plfxlc_mac *mac;
	struct plfxlc_usb *usb;

	/* Either something really bad happened, or
	 * we're just dealing with a DEVICE_INSTALLER.
	 */
	if (!hw)
		return;

	mac = plfxlc_hw_mac(hw);
	usb = &mac->chip.usb;

	del_timer_sync(&usb->tx.tx_retry_timer);
	del_timer_sync(&usb->sta_queue_cleanup);

	ieee80211_unregister_hw(hw);

	plfxlc_chip_disable_rxtx(&mac->chip);

	/* If the disconnect has been caused by a removal of the
	 * driver module, the reset allows reloading of the driver. If the
	 * reset will not be executed here, the upload of the firmware in the
	 * probe function caused by the reloading of the driver will fail.
	 */
	usb_reset_device(interface_to_usbdev(intf));

	plfxlc_mac_release(mac);
	ieee80211_free_hw(hw);
}

static void plfxlc_usb_resume(struct plfxlc_usb *usb)
{
	struct plfxlc_mac *mac = plfxlc_usb_to_mac(usb);
	int r;

	r = plfxlc_op_start(plfxlc_usb_to_hw(usb));
	if (r < 0) {
		dev_warn(plfxlc_usb_dev(usb),
			 "Device resume failed (%d)\n", r);

		if (usb->was_running)
			set_bit(PURELIFI_DEVICE_RUNNING, &mac->flags);

		usb_queue_reset_device(usb->intf);
		return;
	}

	if (mac->type != NL80211_IFTYPE_UNSPECIFIED) {
		r = plfxlc_restore_settings(mac);
		if (r < 0) {
			dev_dbg(plfxlc_usb_dev(usb),
				"Restore failed (%d)\n", r);
			return;
		}
	}
}

static void plfxlc_usb_stop(struct plfxlc_usb *usb)
{
	plfxlc_op_stop(plfxlc_usb_to_hw(usb));
	plfxlc_usb_disable_tx(usb);
	plfxlc_usb_disable_rx(usb);

	usb->initialized = false;
}

static int pre_reset(struct usb_interface *intf)
{
	struct ieee80211_hw *hw = usb_get_intfdata(intf);
	struct plfxlc_mac *mac;
	struct plfxlc_usb *usb;

	if (!hw || intf->condition != USB_INTERFACE_BOUND)
		return 0;

	mac = plfxlc_hw_mac(hw);
	usb = &mac->chip.usb;

	usb->was_running = test_bit(PURELIFI_DEVICE_RUNNING, &mac->flags);

	plfxlc_usb_stop(usb);

	return 0;
}

static int post_reset(struct usb_interface *intf)
{
	struct ieee80211_hw *hw = usb_get_intfdata(intf);
	struct plfxlc_mac *mac;
	struct plfxlc_usb *usb;

	if (!hw || intf->condition != USB_INTERFACE_BOUND)
		return 0;

	mac = plfxlc_hw_mac(hw);
	usb = &mac->chip.usb;

	if (usb->was_running)
		plfxlc_usb_resume(usb);

	return 0;
}

#ifdef CONFIG_PM

static struct plfxlc_usb *get_plfxlc_usb(struct usb_interface *intf)
{
	struct ieee80211_hw *hw = plfxlc_intf_to_hw(intf);
	struct plfxlc_mac *mac;

	/* Either something really bad happened, or
	 * we're just dealing with a DEVICE_INSTALLER.
	 */
	if (!hw)
		return NULL;

	mac = plfxlc_hw_mac(hw);
	return &mac->chip.usb;
}

static int suspend(struct usb_interface *interface,
		   pm_message_t message)
{
	struct plfxlc_usb *pl = get_plfxlc_usb(interface);
	struct plfxlc_mac *mac = plfxlc_usb_to_mac(pl);

	if (!pl)
		return -ENODEV;
	if (pl->initialized == 0)
		return 0;
	pl->was_running = test_bit(PURELIFI_DEVICE_RUNNING, &mac->flags);
	plfxlc_usb_stop(pl);
	return 0;
}

static int resume(struct usb_interface *interface)
{
	struct plfxlc_usb *pl = get_plfxlc_usb(interface);

	if (!pl)
		return -ENODEV;
	if (pl->was_running)
		plfxlc_usb_resume(pl);
	return 0;
}

#endif

static struct usb_driver driver = {
	.name = KBUILD_MODNAME,
	.id_table = usb_ids,
	.probe = probe,
	.disconnect = disconnect,
	.pre_reset = pre_reset,
	.post_reset = post_reset,
#ifdef CONFIG_PM
	.suspend = suspend,
	.resume = resume,
#endif
	.disable_hub_initiated_lpm = 1,
};

static int __init usb_init(void)
{
	int r;

	r = usb_register(&driver);
	if (r) {
		pr_err("%s usb_register() failed %d\n", driver.name, r);
		return r;
	}

	pr_debug("Driver initialized :%s\n", driver.name);
	return 0;
}

static void __exit usb_exit(void)
{
	usb_deregister(&driver);
	pr_debug("%s %s\n", driver.name, __func__);
}

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("USB driver for pureLiFi devices");
MODULE_AUTHOR("pureLiFi");
MODULE_VERSION("1.0");
MODULE_FIRMWARE("plfxlc/lifi-x.bin");
MODULE_DEVICE_TABLE(usb, usb_ids);

module_init(usb_init);
module_exit(usb_exit);
