// 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;
	int r;

	urb = usb_alloc_urb(0, GFP_ATOMIC);
	if (!urb)
		return -ENOMEM;
	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);
