// SPDX-License-Identifier: GPL-2.0
/*
 * Host Wire Adapter:
 * Driver glue, HWA-specific functions, bridges to WAHC and WUSBHC
 *
 * Copyright (C) 2005-2006 Intel Corporation
 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
 *
 * The HWA driver is a simple layer that forwards requests to the WAHC
 * (Wire Adater Host Controller) or WUSBHC (Wireless USB Host
 * Controller) layers.
 *
 * Host Wire Adapter is the 'WUSB 1.0 standard' name for Wireless-USB
 * Host Controller that is connected to your system via USB (a USB
 * dongle that implements a USB host...). There is also a Device Wired
 * Adaptor, DWA (Wireless USB hub) that uses the same mechanism for
 * transferring data (it is after all a USB host connected via
 * Wireless USB), we have a common layer called Wire Adapter Host
 * Controller that does all the hard work. The WUSBHC (Wireless USB
 * Host Controller) is the part common to WUSB Host Controllers, the
 * HWA and the PCI-based one, that is implemented following the WHCI
 * spec. All these layers are implemented in ../wusbcore.
 *
 * The main functions are hwahc_op_urb_{en,de}queue(), that pass the
 * job of converting a URB to a Wire Adapter
 *
 * Entry points:
 *
 *   hwahc_driver_*()   Driver initialization, registration and
 *                      teardown.
 *
 *   hwahc_probe()	New device came up, create an instance for
 *                      it [from device enumeration].
 *
 *   hwahc_disconnect()	Remove device instance [from device
 *                      enumeration].
 *
 *   [__]hwahc_op_*()   Host-Wire-Adaptor specific functions for
 *                      starting/stopping/etc (some might be made also
 *                      DWA).
 */
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/workqueue.h>
#include <linux/wait.h>
#include <linux/completion.h>
#include "../wa-hc.h"
#include "../wusbhc.h"

struct hwahc {
	struct wusbhc wusbhc;	/* has to be 1st */
	struct wahc wa;
};

/*
 * FIXME should be wusbhc
 *
 * NOTE: we need to cache the Cluster ID because later...there is no
 *       way to get it :)
 */
static int __hwahc_set_cluster_id(struct hwahc *hwahc, u8 cluster_id)
{
	int result;
	struct wusbhc *wusbhc = &hwahc->wusbhc;
	struct wahc *wa = &hwahc->wa;
	struct device *dev = &wa->usb_iface->dev;

	result = usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
			WUSB_REQ_SET_CLUSTER_ID,
			USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
			cluster_id,
			wa->usb_iface->cur_altsetting->desc.bInterfaceNumber,
			NULL, 0, USB_CTRL_SET_TIMEOUT);
	if (result < 0)
		dev_err(dev, "Cannot set WUSB Cluster ID to 0x%02x: %d\n",
			cluster_id, result);
	else
		wusbhc->cluster_id = cluster_id;
	dev_info(dev, "Wireless USB Cluster ID set to 0x%02x\n", cluster_id);
	return result;
}

static int __hwahc_op_set_num_dnts(struct wusbhc *wusbhc, u8 interval, u8 slots)
{
	struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
	struct wahc *wa = &hwahc->wa;

	return usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
			WUSB_REQ_SET_NUM_DNTS,
			USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
			interval << 8 | slots,
			wa->usb_iface->cur_altsetting->desc.bInterfaceNumber,
			NULL, 0, USB_CTRL_SET_TIMEOUT);
}

/*
 * Reset a WUSB host controller and wait for it to complete doing it.
 *
 * @usb_hcd:	Pointer to WUSB Host Controller instance.
 *
 */
static int hwahc_op_reset(struct usb_hcd *usb_hcd)
{
	int result;
	struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
	struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
	struct device *dev = &hwahc->wa.usb_iface->dev;

	mutex_lock(&wusbhc->mutex);
	wa_nep_disarm(&hwahc->wa);
	result = __wa_set_feature(&hwahc->wa, WA_RESET);
	if (result < 0) {
		dev_err(dev, "error commanding HC to reset: %d\n", result);
		goto error_unlock;
	}
	result = __wa_wait_status(&hwahc->wa, WA_STATUS_RESETTING, 0);
	if (result < 0) {
		dev_err(dev, "error waiting for HC to reset: %d\n", result);
		goto error_unlock;
	}
error_unlock:
	mutex_unlock(&wusbhc->mutex);
	return result;
}

/*
 * FIXME: break this function up
 */
static int hwahc_op_start(struct usb_hcd *usb_hcd)
{
	u8 addr;
	int result;
	struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
	struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);

	result = -ENOSPC;
	mutex_lock(&wusbhc->mutex);
	addr = wusb_cluster_id_get();
	if (addr == 0)
		goto error_cluster_id_get;
	result = __hwahc_set_cluster_id(hwahc, addr);
	if (result < 0)
		goto error_set_cluster_id;

	usb_hcd->uses_new_polling = 1;
	set_bit(HCD_FLAG_POLL_RH, &usb_hcd->flags);
	usb_hcd->state = HC_STATE_RUNNING;

	/*
	 * prevent USB core from suspending the root hub since
	 * bus_suspend and bus_resume are not yet supported.
	 */
	pm_runtime_get_noresume(&usb_hcd->self.root_hub->dev);

	result = 0;
out:
	mutex_unlock(&wusbhc->mutex);
	return result;

error_set_cluster_id:
	wusb_cluster_id_put(addr);
error_cluster_id_get:
	goto out;

}

/*
 * No need to abort pipes, as when this is called, all the children
 * has been disconnected and that has done it [through
 * usb_disable_interface() -> usb_disable_endpoint() ->
 * hwahc_op_ep_disable() - >rpipe_ep_disable()].
 */
static void hwahc_op_stop(struct usb_hcd *usb_hcd)
{
	struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);

	mutex_lock(&wusbhc->mutex);
	wusb_cluster_id_put(wusbhc->cluster_id);
	mutex_unlock(&wusbhc->mutex);
}

static int hwahc_op_get_frame_number(struct usb_hcd *usb_hcd)
{
	struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
	struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
	struct wahc *wa = &hwahc->wa;

	/*
	 * We cannot query the HWA for the WUSB time since that requires sending
	 * a synchronous URB and this function can be called in_interrupt.
	 * Instead, query the USB frame number for our parent and use that.
	 */
	return usb_get_current_frame_number(wa->usb_dev);
}

static int hwahc_op_urb_enqueue(struct usb_hcd *usb_hcd, struct urb *urb,
				gfp_t gfp)
{
	struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
	struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);

	return wa_urb_enqueue(&hwahc->wa, urb->ep, urb, gfp);
}

static int hwahc_op_urb_dequeue(struct usb_hcd *usb_hcd, struct urb *urb,
				int status)
{
	struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
	struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);

	return wa_urb_dequeue(&hwahc->wa, urb, status);
}

/*
 * Release resources allocated for an endpoint
 *
 * If there is an associated rpipe to this endpoint, go ahead and put it.
 */
static void hwahc_op_endpoint_disable(struct usb_hcd *usb_hcd,
				      struct usb_host_endpoint *ep)
{
	struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
	struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);

	rpipe_ep_disable(&hwahc->wa, ep);
}

static int __hwahc_op_wusbhc_start(struct wusbhc *wusbhc)
{
	int result;
	struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
	struct device *dev = &hwahc->wa.usb_iface->dev;

	result = __wa_set_feature(&hwahc->wa, WA_ENABLE);
	if (result < 0) {
		dev_err(dev, "error commanding HC to start: %d\n", result);
		goto error_stop;
	}
	result = __wa_wait_status(&hwahc->wa, WA_ENABLE, WA_ENABLE);
	if (result < 0) {
		dev_err(dev, "error waiting for HC to start: %d\n", result);
		goto error_stop;
	}
	result = wa_nep_arm(&hwahc->wa, GFP_KERNEL);
	if (result < 0) {
		dev_err(dev, "cannot listen to notifications: %d\n", result);
		goto error_stop;
	}
	/*
	 * If WUSB_QUIRK_ALEREON_HWA_DISABLE_XFER_NOTIFICATIONS is set,
	 *  disable transfer notifications.
	 */
	if (hwahc->wa.quirks &
		WUSB_QUIRK_ALEREON_HWA_DISABLE_XFER_NOTIFICATIONS) {
		struct usb_host_interface *cur_altsetting =
			hwahc->wa.usb_iface->cur_altsetting;

		result = usb_control_msg(hwahc->wa.usb_dev,
				usb_sndctrlpipe(hwahc->wa.usb_dev, 0),
				WA_REQ_ALEREON_DISABLE_XFER_NOTIFICATIONS,
				USB_DIR_OUT | USB_TYPE_VENDOR |
					USB_RECIP_INTERFACE,
				WA_REQ_ALEREON_FEATURE_SET,
				cur_altsetting->desc.bInterfaceNumber,
				NULL, 0,
				USB_CTRL_SET_TIMEOUT);
		/*
		 * If we successfully sent the control message, start DTI here
		 * because no transfer notifications will be received which is
		 * where DTI is normally started.
		 */
		if (result == 0)
			result = wa_dti_start(&hwahc->wa);
		else
			result = 0;	/* OK.  Continue normally. */

		if (result < 0) {
			dev_err(dev, "cannot start DTI: %d\n", result);
			goto error_dti_start;
		}
	}

	return result;

error_dti_start:
	wa_nep_disarm(&hwahc->wa);
error_stop:
	__wa_clear_feature(&hwahc->wa, WA_ENABLE);
	return result;
}

static void __hwahc_op_wusbhc_stop(struct wusbhc *wusbhc, int delay)
{
	struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
	struct wahc *wa = &hwahc->wa;
	u8 iface_no = wa->usb_iface->cur_altsetting->desc.bInterfaceNumber;
	int ret;

	ret = usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
			      WUSB_REQ_CHAN_STOP,
			      USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
			      delay * 1000,
			      iface_no,
			      NULL, 0, USB_CTRL_SET_TIMEOUT);
	if (ret == 0)
		msleep(delay);

	wa_nep_disarm(&hwahc->wa);
	__wa_stop(&hwahc->wa);
}

/*
 * Set the UWB MAS allocation for the WUSB cluster
 *
 * @stream_index: stream to use (-1 for cancelling the allocation)
 * @mas: mas bitmap to use
 */
static int __hwahc_op_bwa_set(struct wusbhc *wusbhc, s8 stream_index,
			      const struct uwb_mas_bm *mas)
{
	int result;
	struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
	struct wahc *wa = &hwahc->wa;
	struct device *dev = &wa->usb_iface->dev;
	u8 mas_le[UWB_NUM_MAS/8];

	/* Set the stream index */
	result = usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
			WUSB_REQ_SET_STREAM_IDX,
			USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
			stream_index,
			wa->usb_iface->cur_altsetting->desc.bInterfaceNumber,
			NULL, 0, USB_CTRL_SET_TIMEOUT);
	if (result < 0) {
		dev_err(dev, "Cannot set WUSB stream index: %d\n", result);
		goto out;
	}
	uwb_mas_bm_copy_le(mas_le, mas);
	/* Set the MAS allocation */
	result = usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
			WUSB_REQ_SET_WUSB_MAS,
			USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
			0, wa->usb_iface->cur_altsetting->desc.bInterfaceNumber,
			mas_le, 32, USB_CTRL_SET_TIMEOUT);
	if (result < 0)
		dev_err(dev, "Cannot set WUSB MAS allocation: %d\n", result);
out:
	return result;
}

/*
 * Add an IE to the host's MMC
 *
 * @interval:    See WUSB1.0[8.5.3.1]
 * @repeat_cnt:  See WUSB1.0[8.5.3.1]
 * @handle:      See WUSB1.0[8.5.3.1]
 * @wuie:        Pointer to the header of the WUSB IE data to add.
 *               MUST BE allocated in a kmalloc buffer (no stack or
 *               vmalloc).
 *
 * NOTE: the format of the WUSB IEs for MMCs are different to the
 *       normal MBOA MAC IEs (IE Id + Length in MBOA MAC vs. Length +
 *       Id in WUSB IEs). Standards...you gotta love'em.
 */
static int __hwahc_op_mmcie_add(struct wusbhc *wusbhc, u8 interval,
				u8 repeat_cnt, u8 handle,
				struct wuie_hdr *wuie)
{
	struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
	struct wahc *wa = &hwahc->wa;
	u8 iface_no = wa->usb_iface->cur_altsetting->desc.bInterfaceNumber;

	return usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
			WUSB_REQ_ADD_MMC_IE,
			USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
			interval << 8 | repeat_cnt,
			handle << 8 | iface_no,
			wuie, wuie->bLength, USB_CTRL_SET_TIMEOUT);
}

/*
 * Remove an IE to the host's MMC
 *
 * @handle:      See WUSB1.0[8.5.3.1]
 */
static int __hwahc_op_mmcie_rm(struct wusbhc *wusbhc, u8 handle)
{
	struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
	struct wahc *wa = &hwahc->wa;
	u8 iface_no = wa->usb_iface->cur_altsetting->desc.bInterfaceNumber;
	return usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
			WUSB_REQ_REMOVE_MMC_IE,
			USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
			0, handle << 8 | iface_no,
			NULL, 0, USB_CTRL_SET_TIMEOUT);
}

/*
 * Update device information for a given fake port
 *
 * @port_idx: Fake port to which device is connected (wusbhc index, not
 *            USB port number).
 */
static int __hwahc_op_dev_info_set(struct wusbhc *wusbhc,
				   struct wusb_dev *wusb_dev)
{
	struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
	struct wahc *wa = &hwahc->wa;
	u8 iface_no = wa->usb_iface->cur_altsetting->desc.bInterfaceNumber;
	struct hwa_dev_info *dev_info;
	int ret;

	/* fill out the Device Info buffer and send it */
	dev_info = kzalloc(sizeof(struct hwa_dev_info), GFP_KERNEL);
	if (!dev_info)
		return -ENOMEM;
	uwb_mas_bm_copy_le(dev_info->bmDeviceAvailability,
			   &wusb_dev->availability);
	dev_info->bDeviceAddress = wusb_dev->addr;

	/*
	 * If the descriptors haven't been read yet, use a default PHY
	 * rate of 53.3 Mbit/s only.  The correct value will be used
	 * when this will be called again as part of the
	 * authentication process (which occurs after the descriptors
	 * have been read).
	 */
	if (wusb_dev->wusb_cap_descr)
		dev_info->wPHYRates = wusb_dev->wusb_cap_descr->wPHYRates;
	else
		dev_info->wPHYRates = cpu_to_le16(USB_WIRELESS_PHY_53);

	ret = usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
			WUSB_REQ_SET_DEV_INFO,
			USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
			0, wusb_dev->port_idx << 8 | iface_no,
			dev_info, sizeof(struct hwa_dev_info),
			USB_CTRL_SET_TIMEOUT);
	kfree(dev_info);
	return ret;
}

/*
 * Set host's idea of which encryption (and key) method to use when
 * talking to ad evice on a given port.
 *
 * If key is NULL, it means disable encryption for that "virtual port"
 * (used when we disconnect).
 */
static int __hwahc_dev_set_key(struct wusbhc *wusbhc, u8 port_idx, u32 tkid,
			       const void *key, size_t key_size,
			       u8 key_idx)
{
	int result = -ENOMEM;
	struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
	struct wahc *wa = &hwahc->wa;
	u8 iface_no = wa->usb_iface->cur_altsetting->desc.bInterfaceNumber;
	struct usb_key_descriptor *keyd;
	size_t keyd_len;

	keyd_len = sizeof(*keyd) + key_size;
	keyd = kzalloc(keyd_len, GFP_KERNEL);
	if (keyd == NULL)
		return -ENOMEM;

	keyd->bLength = keyd_len;
	keyd->bDescriptorType = USB_DT_KEY;
	keyd->tTKID[0] = (tkid >>  0) & 0xff;
	keyd->tTKID[1] = (tkid >>  8) & 0xff;
	keyd->tTKID[2] = (tkid >> 16) & 0xff;
	memcpy(keyd->bKeyData, key, key_size);

	result = usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
			USB_REQ_SET_DESCRIPTOR,
			USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
			USB_DT_KEY << 8 | key_idx,
			port_idx << 8 | iface_no,
			keyd, keyd_len, USB_CTRL_SET_TIMEOUT);

	kzfree(keyd); /* clear keys etc. */
	return result;
}

/*
 * Set host's idea of which encryption (and key) method to use when
 * talking to ad evice on a given port.
 *
 * If key is NULL, it means disable encryption for that "virtual port"
 * (used when we disconnect).
 */
static int __hwahc_op_set_ptk(struct wusbhc *wusbhc, u8 port_idx, u32 tkid,
			      const void *key, size_t key_size)
{
	int result = -ENOMEM;
	struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc);
	struct wahc *wa = &hwahc->wa;
	u8 iface_no = wa->usb_iface->cur_altsetting->desc.bInterfaceNumber;
	u8 encryption_value;

	/* Tell the host which key to use to talk to the device */
	if (key) {
		u8 key_idx = wusb_key_index(0, WUSB_KEY_INDEX_TYPE_PTK,
					    WUSB_KEY_INDEX_ORIGINATOR_HOST);

		result = __hwahc_dev_set_key(wusbhc, port_idx, tkid,
					     key, key_size, key_idx);
		if (result < 0)
			goto error_set_key;
		encryption_value = wusbhc->ccm1_etd->bEncryptionValue;
	} else {
		/* FIXME: this should come from wusbhc->etd[UNSECURE].value */
		encryption_value = 0;
	}

	/* Set the encryption type for communicating with the device */
	result = usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
			USB_REQ_SET_ENCRYPTION,
			USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
			encryption_value, port_idx << 8 | iface_no,
			NULL, 0, USB_CTRL_SET_TIMEOUT);
	if (result < 0)
		dev_err(wusbhc->dev, "Can't set host's WUSB encryption for "
			"port index %u to %s (value %d): %d\n", port_idx,
			wusb_et_name(wusbhc->ccm1_etd->bEncryptionType),
			wusbhc->ccm1_etd->bEncryptionValue, result);
error_set_key:
	return result;
}

/*
 * Set host's GTK key
 */
static int __hwahc_op_set_gtk(struct wusbhc *wusbhc, u32 tkid,
			      const void *key, size_t key_size)
{
	u8 key_idx = wusb_key_index(0, WUSB_KEY_INDEX_TYPE_GTK,
				    WUSB_KEY_INDEX_ORIGINATOR_HOST);

	return __hwahc_dev_set_key(wusbhc, 0, tkid, key, key_size, key_idx);
}

/*
 * Get the Wire Adapter class-specific descriptor
 *
 * NOTE: this descriptor comes with the big bundled configuration
 *       descriptor that includes the interfaces' and endpoints', so
 *       we just look for it in the cached copy kept by the USB stack.
 *
 * NOTE2: We convert LE fields to CPU order.
 */
static int wa_fill_descr(struct wahc *wa)
{
	int result;
	struct device *dev = &wa->usb_iface->dev;
	char *itr;
	struct usb_device *usb_dev = wa->usb_dev;
	struct usb_descriptor_header *hdr;
	struct usb_wa_descriptor *wa_descr;
	size_t itr_size, actconfig_idx;

	actconfig_idx = (usb_dev->actconfig - usb_dev->config) /
			sizeof(usb_dev->config[0]);
	itr = usb_dev->rawdescriptors[actconfig_idx];
	itr_size = le16_to_cpu(usb_dev->actconfig->desc.wTotalLength);
	while (itr_size >= sizeof(*hdr)) {
		hdr = (struct usb_descriptor_header *) itr;
		dev_dbg(dev, "Extra device descriptor: "
			"type %02x/%u bytes @ %zu (%zu left)\n",
			hdr->bDescriptorType, hdr->bLength,
			(itr - usb_dev->rawdescriptors[actconfig_idx]),
			itr_size);
		if (hdr->bDescriptorType == USB_DT_WIRE_ADAPTER)
			goto found;
		itr += hdr->bLength;
		itr_size -= hdr->bLength;
	}
	dev_err(dev, "cannot find Wire Adapter Class descriptor\n");
	return -ENODEV;

found:
	result = -EINVAL;
	if (hdr->bLength > itr_size) {	/* is it available? */
		dev_err(dev, "incomplete Wire Adapter Class descriptor "
			"(%zu bytes left, %u needed)\n",
			itr_size, hdr->bLength);
		goto error;
	}
	if (hdr->bLength < sizeof(*wa->wa_descr)) {
		dev_err(dev, "short Wire Adapter Class descriptor\n");
		goto error;
	}
	wa->wa_descr = wa_descr = (struct usb_wa_descriptor *) hdr;
	if (le16_to_cpu(wa_descr->bcdWAVersion) > 0x0100)
		dev_warn(dev, "Wire Adapter v%d.%d newer than groked v1.0\n",
			 (le16_to_cpu(wa_descr->bcdWAVersion) & 0xff00) >> 8,
			 le16_to_cpu(wa_descr->bcdWAVersion) & 0x00ff);
	result = 0;
error:
	return result;
}

static const struct hc_driver hwahc_hc_driver = {
	.description = "hwa-hcd",
	.product_desc = "Wireless USB HWA host controller",
	.hcd_priv_size = sizeof(struct hwahc) - sizeof(struct usb_hcd),
	.irq = NULL,			/* FIXME */
	.flags = HCD_USB25,
	.reset = hwahc_op_reset,
	.start = hwahc_op_start,
	.stop = hwahc_op_stop,
	.get_frame_number = hwahc_op_get_frame_number,
	.urb_enqueue = hwahc_op_urb_enqueue,
	.urb_dequeue = hwahc_op_urb_dequeue,
	.endpoint_disable = hwahc_op_endpoint_disable,

	.hub_status_data = wusbhc_rh_status_data,
	.hub_control = wusbhc_rh_control,
	.start_port_reset = wusbhc_rh_start_port_reset,
};

static int hwahc_security_create(struct hwahc *hwahc)
{
	int result;
	struct wusbhc *wusbhc = &hwahc->wusbhc;
	struct usb_device *usb_dev = hwahc->wa.usb_dev;
	struct device *dev = &usb_dev->dev;
	struct usb_security_descriptor *secd;
	struct usb_encryption_descriptor *etd;
	void *itr, *top;
	size_t itr_size, needed, bytes;
	u8 index;
	char buf[64];

	/* Find the host's security descriptors in the config descr bundle */
	index = (usb_dev->actconfig - usb_dev->config) /
		sizeof(usb_dev->config[0]);
	itr = usb_dev->rawdescriptors[index];
	itr_size = le16_to_cpu(usb_dev->actconfig->desc.wTotalLength);
	top = itr + itr_size;
	result = __usb_get_extra_descriptor(usb_dev->rawdescriptors[index],
			le16_to_cpu(usb_dev->actconfig->desc.wTotalLength),
			USB_DT_SECURITY, (void **) &secd, sizeof(*secd));
	if (result == -1) {
		dev_warn(dev, "BUG? WUSB host has no security descriptors\n");
		return 0;
	}
	needed = sizeof(*secd);
	if (top - (void *)secd < needed) {
		dev_err(dev, "BUG? Not enough data to process security "
			"descriptor header (%zu bytes left vs %zu needed)\n",
			top - (void *) secd, needed);
		return 0;
	}
	needed = le16_to_cpu(secd->wTotalLength);
	if (top - (void *)secd < needed) {
		dev_err(dev, "BUG? Not enough data to process security "
			"descriptors (%zu bytes left vs %zu needed)\n",
			top - (void *) secd, needed);
		return 0;
	}
	/* Walk over the sec descriptors and store CCM1's on wusbhc */
	itr = (void *) secd + sizeof(*secd);
	top = (void *) secd + le16_to_cpu(secd->wTotalLength);
	index = 0;
	bytes = 0;
	while (itr < top) {
		etd = itr;
		if (top - itr < sizeof(*etd)) {
			dev_err(dev, "BUG: bad host security descriptor; "
				"not enough data (%zu vs %zu left)\n",
				top - itr, sizeof(*etd));
			break;
		}
		if (etd->bLength < sizeof(*etd)) {
			dev_err(dev, "BUG: bad host encryption descriptor; "
				"descriptor is too short "
				"(%zu vs %zu needed)\n",
				(size_t)etd->bLength, sizeof(*etd));
			break;
		}
		itr += etd->bLength;
		bytes += snprintf(buf + bytes, sizeof(buf) - bytes,
				  "%s (0x%02x) ",
				  wusb_et_name(etd->bEncryptionType),
				  etd->bEncryptionValue);
		wusbhc->ccm1_etd = etd;
	}
	dev_info(dev, "supported encryption types: %s\n", buf);
	if (wusbhc->ccm1_etd == NULL) {
		dev_err(dev, "E: host doesn't support CCM-1 crypto\n");
		return 0;
	}
	/* Pretty print what we support */
	return 0;
}

static void hwahc_security_release(struct hwahc *hwahc)
{
	/* nothing to do here so far... */
}

static int hwahc_create(struct hwahc *hwahc, struct usb_interface *iface,
	kernel_ulong_t quirks)
{
	int result;
	struct device *dev = &iface->dev;
	struct wusbhc *wusbhc = &hwahc->wusbhc;
	struct wahc *wa = &hwahc->wa;
	struct usb_device *usb_dev = interface_to_usbdev(iface);

	wa->usb_dev = usb_get_dev(usb_dev);	/* bind the USB device */
	wa->usb_iface = usb_get_intf(iface);
	wusbhc->dev = dev;
	/* defer getting the uwb_rc handle until it is needed since it
	 * may not have been registered by the hwa_rc driver yet. */
	wusbhc->uwb_rc = NULL;
	result = wa_fill_descr(wa);	/* Get the device descriptor */
	if (result < 0)
		goto error_fill_descriptor;
	if (wa->wa_descr->bNumPorts > USB_MAXCHILDREN) {
		dev_err(dev, "FIXME: USB_MAXCHILDREN too low for WUSB "
			"adapter (%u ports)\n", wa->wa_descr->bNumPorts);
		wusbhc->ports_max = USB_MAXCHILDREN;
	} else {
		wusbhc->ports_max = wa->wa_descr->bNumPorts;
	}
	wusbhc->mmcies_max = wa->wa_descr->bNumMMCIEs;
	wusbhc->start = __hwahc_op_wusbhc_start;
	wusbhc->stop = __hwahc_op_wusbhc_stop;
	wusbhc->mmcie_add = __hwahc_op_mmcie_add;
	wusbhc->mmcie_rm = __hwahc_op_mmcie_rm;
	wusbhc->dev_info_set = __hwahc_op_dev_info_set;
	wusbhc->bwa_set = __hwahc_op_bwa_set;
	wusbhc->set_num_dnts = __hwahc_op_set_num_dnts;
	wusbhc->set_ptk = __hwahc_op_set_ptk;
	wusbhc->set_gtk = __hwahc_op_set_gtk;
	result = hwahc_security_create(hwahc);
	if (result < 0) {
		dev_err(dev, "Can't initialize security: %d\n", result);
		goto error_security_create;
	}
	wa->wusb = wusbhc;	/* FIXME: ugly, need to fix */
	result = wusbhc_create(&hwahc->wusbhc);
	if (result < 0) {
		dev_err(dev, "Can't create WUSB HC structures: %d\n", result);
		goto error_wusbhc_create;
	}
	result = wa_create(&hwahc->wa, iface, quirks);
	if (result < 0)
		goto error_wa_create;
	return 0;

error_wa_create:
	wusbhc_destroy(&hwahc->wusbhc);
error_wusbhc_create:
	/* WA Descr fill allocs no resources */
error_security_create:
error_fill_descriptor:
	usb_put_intf(iface);
	usb_put_dev(usb_dev);
	return result;
}

static void hwahc_destroy(struct hwahc *hwahc)
{
	struct wusbhc *wusbhc = &hwahc->wusbhc;

	mutex_lock(&wusbhc->mutex);
	__wa_destroy(&hwahc->wa);
	wusbhc_destroy(&hwahc->wusbhc);
	hwahc_security_release(hwahc);
	hwahc->wusbhc.dev = NULL;
	uwb_rc_put(wusbhc->uwb_rc);
	usb_put_intf(hwahc->wa.usb_iface);
	usb_put_dev(hwahc->wa.usb_dev);
	mutex_unlock(&wusbhc->mutex);
}

static void hwahc_init(struct hwahc *hwahc)
{
	wa_init(&hwahc->wa);
}

static int hwahc_probe(struct usb_interface *usb_iface,
		       const struct usb_device_id *id)
{
	int result;
	struct usb_hcd *usb_hcd;
	struct wusbhc *wusbhc;
	struct hwahc *hwahc;
	struct device *dev = &usb_iface->dev;

	result = -ENOMEM;
	usb_hcd = usb_create_hcd(&hwahc_hc_driver, &usb_iface->dev, "wusb-hwa");
	if (usb_hcd == NULL) {
		dev_err(dev, "unable to allocate instance\n");
		goto error_alloc;
	}
	usb_hcd->wireless = 1;
	usb_hcd->self.sg_tablesize = ~0;
	wusbhc = usb_hcd_to_wusbhc(usb_hcd);
	hwahc = container_of(wusbhc, struct hwahc, wusbhc);
	hwahc_init(hwahc);
	result = hwahc_create(hwahc, usb_iface, id->driver_info);
	if (result < 0) {
		dev_err(dev, "Cannot initialize internals: %d\n", result);
		goto error_hwahc_create;
	}
	result = usb_add_hcd(usb_hcd, 0, 0);
	if (result < 0) {
		dev_err(dev, "Cannot add HCD: %d\n", result);
		goto error_add_hcd;
	}
	device_wakeup_enable(usb_hcd->self.controller);
	result = wusbhc_b_create(&hwahc->wusbhc);
	if (result < 0) {
		dev_err(dev, "Cannot setup phase B of WUSBHC: %d\n", result);
		goto error_wusbhc_b_create;
	}
	return 0;

error_wusbhc_b_create:
	usb_remove_hcd(usb_hcd);
error_add_hcd:
	hwahc_destroy(hwahc);
error_hwahc_create:
	usb_put_hcd(usb_hcd);
error_alloc:
	return result;
}

static void hwahc_disconnect(struct usb_interface *usb_iface)
{
	struct usb_hcd *usb_hcd;
	struct wusbhc *wusbhc;
	struct hwahc *hwahc;

	usb_hcd = usb_get_intfdata(usb_iface);
	wusbhc = usb_hcd_to_wusbhc(usb_hcd);
	hwahc = container_of(wusbhc, struct hwahc, wusbhc);

	wusbhc_b_destroy(&hwahc->wusbhc);
	usb_remove_hcd(usb_hcd);
	hwahc_destroy(hwahc);
	usb_put_hcd(usb_hcd);
}

static const struct usb_device_id hwahc_id_table[] = {
	/* Alereon 5310 */
	{ USB_DEVICE_AND_INTERFACE_INFO(0x13dc, 0x5310, 0xe0, 0x02, 0x01),
	  .driver_info = WUSB_QUIRK_ALEREON_HWA_CONCAT_ISOC |
		WUSB_QUIRK_ALEREON_HWA_DISABLE_XFER_NOTIFICATIONS },
	/* Alereon 5611 */
	{ USB_DEVICE_AND_INTERFACE_INFO(0x13dc, 0x5611, 0xe0, 0x02, 0x01),
	  .driver_info = WUSB_QUIRK_ALEREON_HWA_CONCAT_ISOC |
		WUSB_QUIRK_ALEREON_HWA_DISABLE_XFER_NOTIFICATIONS },
	/* FIXME: use class labels for this */
	{ USB_INTERFACE_INFO(0xe0, 0x02, 0x01), },
	{},
};
MODULE_DEVICE_TABLE(usb, hwahc_id_table);

static struct usb_driver hwahc_driver = {
	.name =		"hwa-hc",
	.probe =	hwahc_probe,
	.disconnect =	hwahc_disconnect,
	.id_table =	hwahc_id_table,
};

module_usb_driver(hwahc_driver);

MODULE_AUTHOR("Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>");
MODULE_DESCRIPTION("Host Wired Adapter USB Host Control Driver");
MODULE_LICENSE("GPL");
