// SPDX-License-Identifier: GPL-2.0
/*
 * Wireless USB - Cable Based Association
 *
 *
 * Copyright (C) 2006 Intel Corporation
 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
 * Copyright (C) 2008 Cambridge Silicon Radio Ltd.
 *
 * WUSB devices have to be paired (associated in WUSB lingo) so
 * that they can connect to the system.
 *
 * One way of pairing is using CBA-Cable Based Association. First
 * time you plug the device with a cable, association is done between
 * host and device and subsequent times, you can connect wirelessly
 * without having to associate again. That's the idea.
 *
 * This driver does nothing Earth shattering. It just provides an
 * interface to chat with the wire-connected device so we can get a
 * CDID (device ID) that might have been previously associated to a
 * CHID (host ID) and to set up a new <CHID,CDID,CK> triplet
 * (connection context), with the CK being the secret, or connection
 * key. This is the pairing data.
 *
 * When a device with the CBA capability connects, the probe routine
 * just creates a bunch of sysfs files that a user space enumeration
 * manager uses to allow it to connect wirelessly to the system or not.
 *
 * The process goes like this:
 *
 * 1. Device plugs, cbaf is loaded, notifications happen.
 *
 * 2. The connection manager (CM) sees a device with CBAF capability
 *    (the wusb_chid etc. files in /sys/devices/blah/OURDEVICE).
 *
 * 3. The CM writes the host name, supported band groups, and the CHID
 *    (host ID) into the wusb_host_name, wusb_host_band_groups and
 *    wusb_chid files. These get sent to the device and the CDID (if
 *    any) for this host is requested.
 *
 * 4. The CM can verify that the device's supported band groups
 *    (wusb_device_band_groups) are compatible with the host.
 *
 * 5. The CM reads the wusb_cdid file.
 *
 * 6. The CM looks up its database
 *
 * 6.1 If it has a matching CHID,CDID entry, the device has been
 *     authorized before (paired) and nothing further needs to be
 *     done.
 *
 * 6.2 If the CDID is zero (or the CM doesn't find a matching CDID in
 *     its database), the device is assumed to be not known.  The CM
 *     may associate the host with device by: writing a randomly
 *     generated CDID to wusb_cdid and then a random CK to wusb_ck
 *     (this uploads the new CC to the device).
 *
 *     CMD may choose to prompt the user before associating with a new
 *     device.
 *
 * 7. Device is unplugged.
 *
 * When the device tries to connect wirelessly, it will present its
 * CDID to the WUSB host controller.  The CM will query the
 * database. If the CHID/CDID pair found, it will (with a 4-way
 * handshake) challenge the device to demonstrate it has the CK secret
 * key (from our database) without actually exchanging it. Once
 * satisfied, crypto keys are derived from the CK, the device is
 * connected and all communication is encrypted.
 *
 * References:
 *   [WUSB-AM] Association Models Supplement to the Certified Wireless
 *             Universal Serial Bus Specification, version 1.0.
 */
#include <linux/module.h>
#include <linux/ctype.h>
#include <linux/usb.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/random.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/uwb.h>
#include <linux/usb/wusb.h>
#include <linux/usb/association.h>

#define CBA_NAME_LEN 0x40 /* [WUSB-AM] table 4-7 */

/* An instance of a Cable-Based-Association-Framework device */
struct cbaf {
	struct usb_device *usb_dev;
	struct usb_interface *usb_iface;
	void *buffer;
	size_t buffer_size;

	struct wusb_ckhdid chid;
	char host_name[CBA_NAME_LEN];
	u16 host_band_groups;

	struct wusb_ckhdid cdid;
	char device_name[CBA_NAME_LEN];
	u16 device_band_groups;

	struct wusb_ckhdid ck;
};

/*
 * Verify that a CBAF USB-interface has what we need
 *
 * According to [WUSB-AM], CBA devices should provide at least two
 * interfaces:
 *  - RETRIEVE_HOST_INFO
 *  - ASSOCIATE
 *
 * If the device doesn't provide these interfaces, we do not know how
 * to deal with it.
 */
static int cbaf_check(struct cbaf *cbaf)
{
	int result;
	struct device *dev = &cbaf->usb_iface->dev;
	struct wusb_cbaf_assoc_info *assoc_info;
	struct wusb_cbaf_assoc_request *assoc_request;
	size_t assoc_size;
	void *itr, *top;
	int ar_rhi = 0, ar_assoc = 0;

	result = usb_control_msg(
		cbaf->usb_dev, usb_rcvctrlpipe(cbaf->usb_dev, 0),
		CBAF_REQ_GET_ASSOCIATION_INFORMATION,
		USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
		0, cbaf->usb_iface->cur_altsetting->desc.bInterfaceNumber,
		cbaf->buffer, cbaf->buffer_size, USB_CTRL_GET_TIMEOUT);
	if (result < 0) {
		dev_err(dev, "Cannot get available association types: %d\n",
			result);
		return result;
	}

	assoc_info = cbaf->buffer;
	if (result < sizeof(*assoc_info)) {
		dev_err(dev, "Not enough data to decode association info "
			"header (%zu vs %zu bytes required)\n",
			(size_t)result, sizeof(*assoc_info));
		return result;
	}

	assoc_size = le16_to_cpu(assoc_info->Length);
	if (result < assoc_size) {
		dev_err(dev, "Not enough data to decode association info "
			"(%zu vs %zu bytes required)\n",
			(size_t)assoc_size, sizeof(*assoc_info));
		return result;
	}
	/*
	 * From now on, we just verify, but won't error out unless we
	 * don't find the AR_TYPE_WUSB_{RETRIEVE_HOST_INFO,ASSOCIATE}
	 * types.
	 */
	itr = cbaf->buffer + sizeof(*assoc_info);
	top = cbaf->buffer + assoc_size;
	dev_dbg(dev, "Found %u association requests (%zu bytes)\n",
		 assoc_info->NumAssociationRequests, assoc_size);

	while (itr < top) {
		u16 ar_type, ar_subtype;
		u32 ar_size;
		const char *ar_name;

		assoc_request = itr;

		if (top - itr < sizeof(*assoc_request)) {
			dev_err(dev, "Not enough data to decode association "
				"request (%zu vs %zu bytes needed)\n",
				top - itr, sizeof(*assoc_request));
			break;
		}

		ar_type = le16_to_cpu(assoc_request->AssociationTypeId);
		ar_subtype = le16_to_cpu(assoc_request->AssociationSubTypeId);
		ar_size = le32_to_cpu(assoc_request->AssociationTypeInfoSize);
		ar_name = "unknown";

		switch (ar_type) {
		case AR_TYPE_WUSB:
			/* Verify we have what is mandated by [WUSB-AM]. */
			switch (ar_subtype) {
			case AR_TYPE_WUSB_RETRIEVE_HOST_INFO:
				ar_name = "RETRIEVE_HOST_INFO";
				ar_rhi = 1;
				break;
			case AR_TYPE_WUSB_ASSOCIATE:
				/* send assoc data */
				ar_name = "ASSOCIATE";
				ar_assoc = 1;
				break;
			}
			break;
		}

		dev_dbg(dev, "Association request #%02u: 0x%04x/%04x "
			 "(%zu bytes): %s\n",
			 assoc_request->AssociationDataIndex, ar_type,
			 ar_subtype, (size_t)ar_size, ar_name);

		itr += sizeof(*assoc_request);
	}

	if (!ar_rhi) {
		dev_err(dev, "Missing RETRIEVE_HOST_INFO association "
			"request\n");
		return -EINVAL;
	}
	if (!ar_assoc) {
		dev_err(dev, "Missing ASSOCIATE association request\n");
		return -EINVAL;
	}

	return 0;
}

static const struct wusb_cbaf_host_info cbaf_host_info_defaults = {
	.AssociationTypeId_hdr    = WUSB_AR_AssociationTypeId,
	.AssociationTypeId	  = cpu_to_le16(AR_TYPE_WUSB),
	.AssociationSubTypeId_hdr = WUSB_AR_AssociationSubTypeId,
	.AssociationSubTypeId = cpu_to_le16(AR_TYPE_WUSB_RETRIEVE_HOST_INFO),
	.CHID_hdr                 = WUSB_AR_CHID,
	.LangID_hdr               = WUSB_AR_LangID,
	.HostFriendlyName_hdr     = WUSB_AR_HostFriendlyName,
};

/* Send WUSB host information (CHID and name) to a CBAF device */
static int cbaf_send_host_info(struct cbaf *cbaf)
{
	struct wusb_cbaf_host_info *hi;
	size_t name_len;
	size_t hi_size;

	hi = cbaf->buffer;
	memset(hi, 0, sizeof(*hi));
	*hi = cbaf_host_info_defaults;
	hi->CHID = cbaf->chid;
	hi->LangID = 0;	/* FIXME: I guess... */
	strlcpy(hi->HostFriendlyName, cbaf->host_name, CBA_NAME_LEN);
	name_len = strlen(cbaf->host_name);
	hi->HostFriendlyName_hdr.len = cpu_to_le16(name_len);
	hi_size = sizeof(*hi) + name_len;

	return usb_control_msg(cbaf->usb_dev,
			usb_sndctrlpipe(cbaf->usb_dev, 0),
			CBAF_REQ_SET_ASSOCIATION_RESPONSE,
			USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
			0x0101,
			cbaf->usb_iface->cur_altsetting->desc.bInterfaceNumber,
			hi, hi_size, USB_CTRL_SET_TIMEOUT);
}

/*
 * Get device's information (CDID) associated to CHID
 *
 * The device will return it's information (CDID, name, bandgroups)
 * associated to the CHID we have set before, or 0 CDID and default
 * name and bandgroup if no CHID set or unknown.
 */
static int cbaf_cdid_get(struct cbaf *cbaf)
{
	int result;
	struct device *dev = &cbaf->usb_iface->dev;
	struct wusb_cbaf_device_info *di;
	size_t needed;

	di = cbaf->buffer;
	result = usb_control_msg(
		cbaf->usb_dev, usb_rcvctrlpipe(cbaf->usb_dev, 0),
		CBAF_REQ_GET_ASSOCIATION_REQUEST,
		USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
		0x0200, cbaf->usb_iface->cur_altsetting->desc.bInterfaceNumber,
		di, cbaf->buffer_size, USB_CTRL_GET_TIMEOUT);
	if (result < 0) {
		dev_err(dev, "Cannot request device information: %d\n",
			result);
		return result;
	}

	needed = result < sizeof(*di) ? sizeof(*di) : le32_to_cpu(di->Length);
	if (result < needed) {
		dev_err(dev, "Not enough data in DEVICE_INFO reply (%zu vs "
			"%zu bytes needed)\n", (size_t)result, needed);
		return -ENOENT;
	}

	strlcpy(cbaf->device_name, di->DeviceFriendlyName, CBA_NAME_LEN);
	cbaf->cdid = di->CDID;
	cbaf->device_band_groups = le16_to_cpu(di->BandGroups);

	return 0;
}

static ssize_t cbaf_wusb_chid_show(struct device *dev,
					struct device_attribute *attr,
					char *buf)
{
	struct usb_interface *iface = to_usb_interface(dev);
	struct cbaf *cbaf = usb_get_intfdata(iface);
	char pr_chid[WUSB_CKHDID_STRSIZE];

	ckhdid_printf(pr_chid, sizeof(pr_chid), &cbaf->chid);
	return scnprintf(buf, PAGE_SIZE, "%s\n", pr_chid);
}

static ssize_t cbaf_wusb_chid_store(struct device *dev,
					 struct device_attribute *attr,
					 const char *buf, size_t size)
{
	ssize_t result;
	struct usb_interface *iface = to_usb_interface(dev);
	struct cbaf *cbaf = usb_get_intfdata(iface);

	result = sscanf(buf,
			"%02hhx %02hhx %02hhx %02hhx "
			"%02hhx %02hhx %02hhx %02hhx "
			"%02hhx %02hhx %02hhx %02hhx "
			"%02hhx %02hhx %02hhx %02hhx",
			&cbaf->chid.data[0] , &cbaf->chid.data[1],
			&cbaf->chid.data[2] , &cbaf->chid.data[3],
			&cbaf->chid.data[4] , &cbaf->chid.data[5],
			&cbaf->chid.data[6] , &cbaf->chid.data[7],
			&cbaf->chid.data[8] , &cbaf->chid.data[9],
			&cbaf->chid.data[10], &cbaf->chid.data[11],
			&cbaf->chid.data[12], &cbaf->chid.data[13],
			&cbaf->chid.data[14], &cbaf->chid.data[15]);

	if (result != 16)
		return -EINVAL;

	result = cbaf_send_host_info(cbaf);
	if (result < 0)
		return result;
	result = cbaf_cdid_get(cbaf);
	if (result < 0)
		return result;
	return size;
}
static DEVICE_ATTR(wusb_chid, 0600, cbaf_wusb_chid_show, cbaf_wusb_chid_store);

static ssize_t cbaf_wusb_host_name_show(struct device *dev,
					struct device_attribute *attr,
					char *buf)
{
	struct usb_interface *iface = to_usb_interface(dev);
	struct cbaf *cbaf = usb_get_intfdata(iface);

	return scnprintf(buf, PAGE_SIZE, "%s\n", cbaf->host_name);
}

static ssize_t cbaf_wusb_host_name_store(struct device *dev,
					 struct device_attribute *attr,
					 const char *buf, size_t size)
{
	ssize_t result;
	struct usb_interface *iface = to_usb_interface(dev);
	struct cbaf *cbaf = usb_get_intfdata(iface);

	result = sscanf(buf, "%63s", cbaf->host_name);
	if (result != 1)
		return -EINVAL;

	return size;
}
static DEVICE_ATTR(wusb_host_name, 0600, cbaf_wusb_host_name_show,
					 cbaf_wusb_host_name_store);

static ssize_t cbaf_wusb_host_band_groups_show(struct device *dev,
					       struct device_attribute *attr,
					       char *buf)
{
	struct usb_interface *iface = to_usb_interface(dev);
	struct cbaf *cbaf = usb_get_intfdata(iface);

	return scnprintf(buf, PAGE_SIZE, "0x%04x\n", cbaf->host_band_groups);
}

static ssize_t cbaf_wusb_host_band_groups_store(struct device *dev,
						struct device_attribute *attr,
						const char *buf, size_t size)
{
	ssize_t result;
	struct usb_interface *iface = to_usb_interface(dev);
	struct cbaf *cbaf = usb_get_intfdata(iface);
	u16 band_groups = 0;

	result = sscanf(buf, "%04hx", &band_groups);
	if (result != 1)
		return -EINVAL;

	cbaf->host_band_groups = band_groups;

	return size;
}

static DEVICE_ATTR(wusb_host_band_groups, 0600,
		   cbaf_wusb_host_band_groups_show,
		   cbaf_wusb_host_band_groups_store);

static const struct wusb_cbaf_device_info cbaf_device_info_defaults = {
	.Length_hdr               = WUSB_AR_Length,
	.CDID_hdr                 = WUSB_AR_CDID,
	.BandGroups_hdr           = WUSB_AR_BandGroups,
	.LangID_hdr               = WUSB_AR_LangID,
	.DeviceFriendlyName_hdr   = WUSB_AR_DeviceFriendlyName,
};

static ssize_t cbaf_wusb_cdid_show(struct device *dev,
				   struct device_attribute *attr, char *buf)
{
	struct usb_interface *iface = to_usb_interface(dev);
	struct cbaf *cbaf = usb_get_intfdata(iface);
	char pr_cdid[WUSB_CKHDID_STRSIZE];

	ckhdid_printf(pr_cdid, sizeof(pr_cdid), &cbaf->cdid);
	return scnprintf(buf, PAGE_SIZE, "%s\n", pr_cdid);
}

static ssize_t cbaf_wusb_cdid_store(struct device *dev,
				struct device_attribute *attr,
				const char *buf, size_t size)
{
	ssize_t result;
	struct usb_interface *iface = to_usb_interface(dev);
	struct cbaf *cbaf = usb_get_intfdata(iface);
	struct wusb_ckhdid cdid;

	result = sscanf(buf,
			"%02hhx %02hhx %02hhx %02hhx "
			"%02hhx %02hhx %02hhx %02hhx "
			"%02hhx %02hhx %02hhx %02hhx "
			"%02hhx %02hhx %02hhx %02hhx",
			&cdid.data[0] , &cdid.data[1],
			&cdid.data[2] , &cdid.data[3],
			&cdid.data[4] , &cdid.data[5],
			&cdid.data[6] , &cdid.data[7],
			&cdid.data[8] , &cdid.data[9],
			&cdid.data[10], &cdid.data[11],
			&cdid.data[12], &cdid.data[13],
			&cdid.data[14], &cdid.data[15]);
	if (result != 16)
		return -EINVAL;

	cbaf->cdid = cdid;

	return size;
}
static DEVICE_ATTR(wusb_cdid, 0600, cbaf_wusb_cdid_show, cbaf_wusb_cdid_store);

static ssize_t cbaf_wusb_device_band_groups_show(struct device *dev,
						 struct device_attribute *attr,
						 char *buf)
{
	struct usb_interface *iface = to_usb_interface(dev);
	struct cbaf *cbaf = usb_get_intfdata(iface);

	return scnprintf(buf, PAGE_SIZE, "0x%04x\n", cbaf->device_band_groups);
}

static DEVICE_ATTR(wusb_device_band_groups, 0600,
		   cbaf_wusb_device_band_groups_show,
		   NULL);

static ssize_t cbaf_wusb_device_name_show(struct device *dev,
					struct device_attribute *attr,
					char *buf)
{
	struct usb_interface *iface = to_usb_interface(dev);
	struct cbaf *cbaf = usb_get_intfdata(iface);

	return scnprintf(buf, PAGE_SIZE, "%s\n", cbaf->device_name);
}
static DEVICE_ATTR(wusb_device_name, 0600, cbaf_wusb_device_name_show, NULL);

static const struct wusb_cbaf_cc_data cbaf_cc_data_defaults = {
	.AssociationTypeId_hdr    = WUSB_AR_AssociationTypeId,
	.AssociationTypeId	  = cpu_to_le16(AR_TYPE_WUSB),
	.AssociationSubTypeId_hdr = WUSB_AR_AssociationSubTypeId,
	.AssociationSubTypeId     = cpu_to_le16(AR_TYPE_WUSB_ASSOCIATE),
	.Length_hdr               = WUSB_AR_Length,
	.Length		= cpu_to_le32(sizeof(struct wusb_cbaf_cc_data)),
	.ConnectionContext_hdr    = WUSB_AR_ConnectionContext,
	.BandGroups_hdr           = WUSB_AR_BandGroups,
};

static const struct wusb_cbaf_cc_data_fail cbaf_cc_data_fail_defaults = {
	.AssociationTypeId_hdr    = WUSB_AR_AssociationTypeId,
	.AssociationSubTypeId_hdr = WUSB_AR_AssociationSubTypeId,
	.Length_hdr               = WUSB_AR_Length,
	.AssociationStatus_hdr    = WUSB_AR_AssociationStatus,
};

/*
 * Send a new CC to the device.
 */
static int cbaf_cc_upload(struct cbaf *cbaf)
{
	int result;
	struct device *dev = &cbaf->usb_iface->dev;
	struct wusb_cbaf_cc_data *ccd;
	char pr_cdid[WUSB_CKHDID_STRSIZE];

	ccd =  cbaf->buffer;
	*ccd = cbaf_cc_data_defaults;
	ccd->CHID = cbaf->chid;
	ccd->CDID = cbaf->cdid;
	ccd->CK = cbaf->ck;
	ccd->BandGroups = cpu_to_le16(cbaf->host_band_groups);

	dev_dbg(dev, "Trying to upload CC:\n");
	ckhdid_printf(pr_cdid, sizeof(pr_cdid), &ccd->CHID);
	dev_dbg(dev, "  CHID       %s\n", pr_cdid);
	ckhdid_printf(pr_cdid, sizeof(pr_cdid), &ccd->CDID);
	dev_dbg(dev, "  CDID       %s\n", pr_cdid);
	dev_dbg(dev, "  Bandgroups 0x%04x\n", cbaf->host_band_groups);

	result = usb_control_msg(
		cbaf->usb_dev, usb_sndctrlpipe(cbaf->usb_dev, 0),
		CBAF_REQ_SET_ASSOCIATION_RESPONSE,
		USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
		0x0201, cbaf->usb_iface->cur_altsetting->desc.bInterfaceNumber,
		ccd, sizeof(*ccd), USB_CTRL_SET_TIMEOUT);

	return result;
}

static ssize_t cbaf_wusb_ck_store(struct device *dev,
				  struct device_attribute *attr,
				  const char *buf, size_t size)
{
	ssize_t result;
	struct usb_interface *iface = to_usb_interface(dev);
	struct cbaf *cbaf = usb_get_intfdata(iface);

	result = sscanf(buf,
			"%02hhx %02hhx %02hhx %02hhx "
			"%02hhx %02hhx %02hhx %02hhx "
			"%02hhx %02hhx %02hhx %02hhx "
			"%02hhx %02hhx %02hhx %02hhx",
			&cbaf->ck.data[0] , &cbaf->ck.data[1],
			&cbaf->ck.data[2] , &cbaf->ck.data[3],
			&cbaf->ck.data[4] , &cbaf->ck.data[5],
			&cbaf->ck.data[6] , &cbaf->ck.data[7],
			&cbaf->ck.data[8] , &cbaf->ck.data[9],
			&cbaf->ck.data[10], &cbaf->ck.data[11],
			&cbaf->ck.data[12], &cbaf->ck.data[13],
			&cbaf->ck.data[14], &cbaf->ck.data[15]);
	if (result != 16)
		return -EINVAL;

	result = cbaf_cc_upload(cbaf);
	if (result < 0)
		return result;

	return size;
}
static DEVICE_ATTR(wusb_ck, 0600, NULL, cbaf_wusb_ck_store);

static struct attribute *cbaf_dev_attrs[] = {
	&dev_attr_wusb_host_name.attr,
	&dev_attr_wusb_host_band_groups.attr,
	&dev_attr_wusb_chid.attr,
	&dev_attr_wusb_cdid.attr,
	&dev_attr_wusb_device_name.attr,
	&dev_attr_wusb_device_band_groups.attr,
	&dev_attr_wusb_ck.attr,
	NULL,
};

static const struct attribute_group cbaf_dev_attr_group = {
	.name = NULL,	/* we want them in the same directory */
	.attrs = cbaf_dev_attrs,
};

static int cbaf_probe(struct usb_interface *iface,
		      const struct usb_device_id *id)
{
	struct cbaf *cbaf;
	struct device *dev = &iface->dev;
	int result = -ENOMEM;

	cbaf = kzalloc(sizeof(*cbaf), GFP_KERNEL);
	if (cbaf == NULL)
		goto error_kzalloc;
	cbaf->buffer = kmalloc(512, GFP_KERNEL);
	if (cbaf->buffer == NULL)
		goto error_kmalloc_buffer;

	cbaf->buffer_size = 512;
	cbaf->usb_dev = usb_get_dev(interface_to_usbdev(iface));
	cbaf->usb_iface = usb_get_intf(iface);
	result = cbaf_check(cbaf);
	if (result < 0) {
		dev_err(dev, "This device is not WUSB-CBAF compliant and is not supported yet.\n");
		goto error_check;
	}

	result = sysfs_create_group(&dev->kobj, &cbaf_dev_attr_group);
	if (result < 0) {
		dev_err(dev, "Can't register sysfs attr group: %d\n", result);
		goto error_create_group;
	}
	usb_set_intfdata(iface, cbaf);
	return 0;

error_create_group:
error_check:
	usb_put_intf(iface);
	usb_put_dev(cbaf->usb_dev);
	kfree(cbaf->buffer);
error_kmalloc_buffer:
	kfree(cbaf);
error_kzalloc:
	return result;
}

static void cbaf_disconnect(struct usb_interface *iface)
{
	struct cbaf *cbaf = usb_get_intfdata(iface);
	struct device *dev = &iface->dev;
	sysfs_remove_group(&dev->kobj, &cbaf_dev_attr_group);
	usb_set_intfdata(iface, NULL);
	usb_put_intf(iface);
	usb_put_dev(cbaf->usb_dev);
	kfree(cbaf->buffer);
	/* paranoia: clean up crypto keys */
	kzfree(cbaf);
}

static const struct usb_device_id cbaf_id_table[] = {
	{ USB_INTERFACE_INFO(0xef, 0x03, 0x01), },
	{ },
};
MODULE_DEVICE_TABLE(usb, cbaf_id_table);

static struct usb_driver cbaf_driver = {
	.name =		"wusb-cbaf",
	.id_table =	cbaf_id_table,
	.probe =	cbaf_probe,
	.disconnect =	cbaf_disconnect,
};

module_usb_driver(cbaf_driver);

MODULE_AUTHOR("Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>");
MODULE_DESCRIPTION("Wireless USB Cable Based Association");
MODULE_LICENSE("GPL");
