/*
 * Wireless USB Host Controller
 * sysfs glue, wusbcore module support and life cycle management
 *
 *
 * Copyright (C) 2005-2006 Intel Corporation
 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version
 * 2 as published by the Free Software Foundation.
 *
 * 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; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 *
 * Creation/destruction of wusbhc is split in two parts; that that
 * doesn't require the HCD to be added (wusbhc_{create,destroy}) and
 * the one that requires (phase B, wusbhc_b_{create,destroy}).
 *
 * This is so because usb_add_hcd() will start the HC, and thus, all
 * the HC specific stuff has to be already initialized (like sysfs
 * thingies).
 */
#include <linux/device.h>
#include <linux/module.h>
#include "wusbhc.h"

/**
 * Extract the wusbhc that corresponds to a USB Host Controller class device
 *
 * WARNING! Apply only if @dev is that of a
 *          wusbhc.usb_hcd.self->class_dev; otherwise, you loose.
 */
static struct wusbhc *usbhc_dev_to_wusbhc(struct device *dev)
{
	struct usb_bus *usb_bus = dev_get_drvdata(dev);
	struct usb_hcd *usb_hcd = bus_to_hcd(usb_bus);
	return usb_hcd_to_wusbhc(usb_hcd);
}

/*
 * Show & store the current WUSB trust timeout
 *
 * We don't do locking--it is an 'atomic' value.
 *
 * The units that we store/show are always MILLISECONDS. However, the
 * value of trust_timeout is jiffies.
 */
static ssize_t wusb_trust_timeout_show(struct device *dev,
					struct device_attribute *attr,
					char *buf)
{
	struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev);

	return scnprintf(buf, PAGE_SIZE, "%u\n", wusbhc->trust_timeout);
}

static ssize_t wusb_trust_timeout_store(struct device *dev,
					struct device_attribute *attr,
					const char *buf, size_t size)
{
	struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev);
	ssize_t result = -ENOSYS;
	unsigned trust_timeout;

	result = sscanf(buf, "%u", &trust_timeout);
	if (result != 1) {
		result = -EINVAL;
		goto out;
	}
	wusbhc->trust_timeout = min_t(unsigned, trust_timeout, 500);
	cancel_delayed_work(&wusbhc->keep_alive_timer);
	flush_workqueue(wusbd);
	queue_delayed_work(wusbd, &wusbhc->keep_alive_timer,
			   msecs_to_jiffies(wusbhc->trust_timeout / 2));
out:
	return result < 0 ? result : size;
}
static DEVICE_ATTR(wusb_trust_timeout, 0644, wusb_trust_timeout_show,
					     wusb_trust_timeout_store);

/*
 * Show the current WUSB CHID.
 */
static ssize_t wusb_chid_show(struct device *dev,
			      struct device_attribute *attr, char *buf)
{
	struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev);
	const struct wusb_ckhdid *chid;
	ssize_t result = 0;

	if (wusbhc->wuie_host_info != NULL)
		chid = &wusbhc->wuie_host_info->CHID;
	else
		chid = &wusb_ckhdid_zero;

	result += ckhdid_printf(buf, PAGE_SIZE, chid);
	result += sprintf(buf + result, "\n");

	return result;
}

/*
 * Store a new CHID.
 *
 * - Write an all zeros CHID and it will stop the controller
 * - Write a non-zero CHID and it will start it.
 *
 * See wusbhc_chid_set() for more info.
 */
static ssize_t wusb_chid_store(struct device *dev,
			       struct device_attribute *attr,
			       const char *buf, size_t size)
{
	struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev);
	struct wusb_ckhdid chid;
	ssize_t result;

	result = sscanf(buf,
			"%02hhx %02hhx %02hhx %02hhx "
			"%02hhx %02hhx %02hhx %02hhx "
			"%02hhx %02hhx %02hhx %02hhx "
			"%02hhx %02hhx %02hhx %02hhx\n",
			&chid.data[0] , &chid.data[1] ,
			&chid.data[2] , &chid.data[3] ,
			&chid.data[4] , &chid.data[5] ,
			&chid.data[6] , &chid.data[7] ,
			&chid.data[8] , &chid.data[9] ,
			&chid.data[10], &chid.data[11],
			&chid.data[12], &chid.data[13],
			&chid.data[14], &chid.data[15]);
	if (result != 16) {
		dev_err(dev, "Unrecognized CHID (need 16 8-bit hex digits): "
			"%d\n", (int)result);
		return -EINVAL;
	}
	result = wusbhc_chid_set(wusbhc, &chid);
	return result < 0 ? result : size;
}
static DEVICE_ATTR(wusb_chid, 0644, wusb_chid_show, wusb_chid_store);


static ssize_t wusb_phy_rate_show(struct device *dev,
				  struct device_attribute *attr,
				  char *buf)
{
	struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev);

	return sprintf(buf, "%d\n", wusbhc->phy_rate);
}

static ssize_t wusb_phy_rate_store(struct device *dev,
				   struct device_attribute *attr,
				   const char *buf, size_t size)
{
	struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev);
	uint8_t phy_rate;
	ssize_t result;

	result = sscanf(buf, "%hhu", &phy_rate);
	if (result != 1)
		return -EINVAL;
	if (phy_rate >= UWB_PHY_RATE_INVALID)
		return -EINVAL;

	wusbhc->phy_rate = phy_rate;
	return size;
}
static DEVICE_ATTR(wusb_phy_rate, 0644, wusb_phy_rate_show,
			wusb_phy_rate_store);

static ssize_t wusb_dnts_show(struct device *dev,
				  struct device_attribute *attr,
				  char *buf)
{
	struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev);

	return sprintf(buf, "num slots: %d\ninterval: %dms\n",
			wusbhc->dnts_num_slots, wusbhc->dnts_interval);
}

static ssize_t wusb_dnts_store(struct device *dev,
				   struct device_attribute *attr,
				   const char *buf, size_t size)
{
	struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev);
	uint8_t num_slots, interval;
	ssize_t result;

	result = sscanf(buf, "%hhu %hhu", &num_slots, &interval);

	if (result != 2)
		return -EINVAL;

	wusbhc->dnts_num_slots = num_slots;
	wusbhc->dnts_interval = interval;

	return size;
}
static DEVICE_ATTR(wusb_dnts, 0644, wusb_dnts_show, wusb_dnts_store);

static ssize_t wusb_retry_count_show(struct device *dev,
				  struct device_attribute *attr,
				  char *buf)
{
	struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev);

	return sprintf(buf, "%d\n", wusbhc->retry_count);
}

static ssize_t wusb_retry_count_store(struct device *dev,
				   struct device_attribute *attr,
				   const char *buf, size_t size)
{
	struct wusbhc *wusbhc = usbhc_dev_to_wusbhc(dev);
	uint8_t retry_count;
	ssize_t result;

	result = sscanf(buf, "%hhu", &retry_count);

	if (result != 1)
		return -EINVAL;

	wusbhc->retry_count = max_t(uint8_t, retry_count,
					WUSB_RETRY_COUNT_MAX);

	return size;
}
static DEVICE_ATTR(wusb_retry_count, 0644, wusb_retry_count_show,
	wusb_retry_count_store);

/* Group all the WUSBHC attributes */
static struct attribute *wusbhc_attrs[] = {
		&dev_attr_wusb_trust_timeout.attr,
		&dev_attr_wusb_chid.attr,
		&dev_attr_wusb_phy_rate.attr,
		&dev_attr_wusb_dnts.attr,
		&dev_attr_wusb_retry_count.attr,
		NULL,
};

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

/*
 * Create a wusbhc instance
 *
 * NOTEs:
 *
 *  - assumes *wusbhc has been zeroed and wusbhc->usb_hcd has been
 *    initialized but not added.
 *
 *  - fill out ports_max, mmcies_max and mmcie_{add,rm} before calling.
 *
 *  - fill out wusbhc->uwb_rc and refcount it before calling
 *  - fill out the wusbhc->sec_modes array
 */
int wusbhc_create(struct wusbhc *wusbhc)
{
	int result = 0;

	/* set defaults.  These can be overwritten using sysfs attributes. */
	wusbhc->trust_timeout = WUSB_TRUST_TIMEOUT_MS;
	wusbhc->phy_rate = UWB_PHY_RATE_INVALID - 1;
	wusbhc->dnts_num_slots = 4;
	wusbhc->dnts_interval = 2;
	wusbhc->retry_count = WUSB_RETRY_COUNT_INFINITE;

	mutex_init(&wusbhc->mutex);
	result = wusbhc_mmcie_create(wusbhc);
	if (result < 0)
		goto error_mmcie_create;
	result = wusbhc_devconnect_create(wusbhc);
	if (result < 0)
		goto error_devconnect_create;
	result = wusbhc_rh_create(wusbhc);
	if (result < 0)
		goto error_rh_create;
	result = wusbhc_sec_create(wusbhc);
	if (result < 0)
		goto error_sec_create;
	return 0;

error_sec_create:
	wusbhc_rh_destroy(wusbhc);
error_rh_create:
	wusbhc_devconnect_destroy(wusbhc);
error_devconnect_create:
	wusbhc_mmcie_destroy(wusbhc);
error_mmcie_create:
	return result;
}
EXPORT_SYMBOL_GPL(wusbhc_create);

static inline struct kobject *wusbhc_kobj(struct wusbhc *wusbhc)
{
	return &wusbhc->usb_hcd.self.controller->kobj;
}

/*
 * Phase B of a wusbhc instance creation
 *
 * Creates fields that depend on wusbhc->usb_hcd having been
 * added. This is where we create the sysfs files in
 * /sys/class/usb_host/usb_hostX/.
 *
 * NOTE: Assumes wusbhc->usb_hcd has been already added by the upper
 *       layer (hwahc or whci)
 */
int wusbhc_b_create(struct wusbhc *wusbhc)
{
	int result = 0;
	struct device *dev = wusbhc->usb_hcd.self.controller;

	result = sysfs_create_group(wusbhc_kobj(wusbhc), &wusbhc_attr_group);
	if (result < 0) {
		dev_err(dev, "Cannot register WUSBHC attributes: %d\n",
			result);
		goto error_create_attr_group;
	}

	return 0;
error_create_attr_group:
	return result;
}
EXPORT_SYMBOL_GPL(wusbhc_b_create);

void wusbhc_b_destroy(struct wusbhc *wusbhc)
{
	wusbhc_pal_unregister(wusbhc);
	sysfs_remove_group(wusbhc_kobj(wusbhc), &wusbhc_attr_group);
}
EXPORT_SYMBOL_GPL(wusbhc_b_destroy);

void wusbhc_destroy(struct wusbhc *wusbhc)
{
	wusbhc_sec_destroy(wusbhc);
	wusbhc_rh_destroy(wusbhc);
	wusbhc_devconnect_destroy(wusbhc);
	wusbhc_mmcie_destroy(wusbhc);
}
EXPORT_SYMBOL_GPL(wusbhc_destroy);

struct workqueue_struct *wusbd;
EXPORT_SYMBOL_GPL(wusbd);

/*
 * WUSB Cluster ID allocation map
 *
 * Each WUSB bus in a channel is identified with a Cluster Id in the
 * unauth address pace (WUSB1.0[4.3]). We take the range 0xe0 to 0xff
 * (that's space for 31 WUSB controllers, as 0xff can't be taken). We
 * start taking from 0xff, 0xfe, 0xfd... (hence the += or -= 0xff).
 *
 * For each one we taken, we pin it in the bitap
 */
#define CLUSTER_IDS 32
static DECLARE_BITMAP(wusb_cluster_id_table, CLUSTER_IDS);
static DEFINE_SPINLOCK(wusb_cluster_ids_lock);

/*
 * Get a WUSB Cluster ID
 *
 * Need to release with wusb_cluster_id_put() when done w/ it.
 */
/* FIXME: coordinate with the choose_addres() from the USB stack */
/* we want to leave the top of the 128 range for cluster addresses and
 * the bottom for device addresses (as we map them one on one with
 * ports). */
u8 wusb_cluster_id_get(void)
{
	u8 id;
	spin_lock(&wusb_cluster_ids_lock);
	id = find_first_zero_bit(wusb_cluster_id_table, CLUSTER_IDS);
	if (id >= CLUSTER_IDS) {
		id = 0;
		goto out;
	}
	set_bit(id, wusb_cluster_id_table);
	id = (u8) 0xff - id;
out:
	spin_unlock(&wusb_cluster_ids_lock);
	return id;

}
EXPORT_SYMBOL_GPL(wusb_cluster_id_get);

/*
 * Release a WUSB Cluster ID
 *
 * Obtained it with wusb_cluster_id_get()
 */
void wusb_cluster_id_put(u8 id)
{
	id = 0xff - id;
	BUG_ON(id >= CLUSTER_IDS);
	spin_lock(&wusb_cluster_ids_lock);
	WARN_ON(!test_bit(id, wusb_cluster_id_table));
	clear_bit(id, wusb_cluster_id_table);
	spin_unlock(&wusb_cluster_ids_lock);
}
EXPORT_SYMBOL_GPL(wusb_cluster_id_put);

/**
 * wusbhc_giveback_urb - return an URB to the USB core
 * @wusbhc: the host controller the URB is from.
 * @urb:    the URB.
 * @status: the URB's status.
 *
 * Return an URB to the USB core doing some additional WUSB specific
 * processing.
 *
 *  - After a successful transfer, update the trust timeout timestamp
 *    for the WUSB device.
 *
 *  - [WUSB] sections 4.13 and 7.5.1 specify the stop retransmission
 *    condition for the WCONNECTACK_IE is that the host has observed
 *    the associated device responding to a control transfer.
 */
void wusbhc_giveback_urb(struct wusbhc *wusbhc, struct urb *urb, int status)
{
	struct wusb_dev *wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc,
					urb->dev);

	if (status == 0 && wusb_dev) {
		wusb_dev->entry_ts = jiffies;

		/* wusbhc_devconnect_acked() can't be called from
		   atomic context so defer it to a work queue. */
		if (!list_empty(&wusb_dev->cack_node))
			queue_work(wusbd, &wusb_dev->devconnect_acked_work);
		else
			wusb_dev_put(wusb_dev);
	}

	usb_hcd_giveback_urb(&wusbhc->usb_hcd, urb, status);
}
EXPORT_SYMBOL_GPL(wusbhc_giveback_urb);

/**
 * wusbhc_reset_all - reset the HC hardware
 * @wusbhc: the host controller to reset.
 *
 * Request a full hardware reset of the chip.  This will also reset
 * the radio controller and any other PALs.
 */
void wusbhc_reset_all(struct wusbhc *wusbhc)
{
	if (wusbhc->uwb_rc)
		uwb_rc_reset_all(wusbhc->uwb_rc);
}
EXPORT_SYMBOL_GPL(wusbhc_reset_all);

static struct notifier_block wusb_usb_notifier = {
	.notifier_call = wusb_usb_ncb,
	.priority = INT_MAX	/* Need to be called first of all */
};

static int __init wusbcore_init(void)
{
	int result;
	result = wusb_crypto_init();
	if (result < 0)
		goto error_crypto_init;
	/* WQ is singlethread because we need to serialize notifications */
	wusbd = create_singlethread_workqueue("wusbd");
	if (wusbd == NULL) {
		result = -ENOMEM;
		printk(KERN_ERR "WUSB-core: Cannot create wusbd workqueue\n");
		goto error_wusbd_create;
	}
	usb_register_notify(&wusb_usb_notifier);
	bitmap_zero(wusb_cluster_id_table, CLUSTER_IDS);
	set_bit(0, wusb_cluster_id_table);	/* reserve Cluster ID 0xff */
	return 0;

error_wusbd_create:
	wusb_crypto_exit();
error_crypto_init:
	return result;

}
module_init(wusbcore_init);

static void __exit wusbcore_exit(void)
{
	clear_bit(0, wusb_cluster_id_table);
	if (!bitmap_empty(wusb_cluster_id_table, CLUSTER_IDS)) {
		printk(KERN_ERR "BUG: WUSB Cluster IDs not released on exit: %*pb\n",
		       CLUSTER_IDS, wusb_cluster_id_table);
		WARN_ON(1);
	}
	usb_unregister_notify(&wusb_usb_notifier);
	destroy_workqueue(wusbd);
	wusb_crypto_exit();
}
module_exit(wusbcore_exit);

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