/*
 * Ultra Wide Band
 * Life cycle of radio controllers
 *
 * 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.
 *
 *
 * FIXME: docs
 *
 * A UWB radio controller is also a UWB device, so it embeds one...
 *
 * List of RCs comes from the 'struct class uwb_rc_class'.
 */

#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/random.h>
#include <linux/kdev_t.h>
#include <linux/etherdevice.h>
#include <linux/usb.h>
#include <linux/slab.h>
#include <linux/export.h>

#include "uwb-internal.h"

static int uwb_rc_index_match(struct device *dev, const void *data)
{
	const int *index = data;
	struct uwb_rc *rc = dev_get_drvdata(dev);

	if (rc->index == *index)
		return 1;
	return 0;
}

static struct uwb_rc *uwb_rc_find_by_index(int index)
{
	struct device *dev;
	struct uwb_rc *rc = NULL;

	dev = class_find_device(&uwb_rc_class, NULL, &index, uwb_rc_index_match);
	if (dev) {
		rc = dev_get_drvdata(dev);
		put_device(dev);
	}

	return rc;
}

static int uwb_rc_new_index(void)
{
	int index = 0;

	for (;;) {
		if (!uwb_rc_find_by_index(index))
			return index;
		if (++index < 0)
			index = 0;
	}
}

/**
 * Release the backing device of a uwb_rc that has been dynamically allocated.
 */
static void uwb_rc_sys_release(struct device *dev)
{
	struct uwb_dev *uwb_dev = container_of(dev, struct uwb_dev, dev);
	struct uwb_rc *rc = container_of(uwb_dev, struct uwb_rc, uwb_dev);

	uwb_rc_ie_release(rc);
	kfree(rc);
}


void uwb_rc_init(struct uwb_rc *rc)
{
	struct uwb_dev *uwb_dev = &rc->uwb_dev;

	uwb_dev_init(uwb_dev);
	rc->uwb_dev.dev.class = &uwb_rc_class;
	rc->uwb_dev.dev.release = uwb_rc_sys_release;
	uwb_rc_neh_create(rc);
	rc->beaconing = -1;
	rc->scan_type = UWB_SCAN_DISABLED;
	INIT_LIST_HEAD(&rc->notifs_chain.list);
	mutex_init(&rc->notifs_chain.mutex);
	INIT_LIST_HEAD(&rc->uwb_beca.list);
	mutex_init(&rc->uwb_beca.mutex);
	uwb_drp_avail_init(rc);
	uwb_rc_ie_init(rc);
	uwb_rsv_init(rc);
	uwb_rc_pal_init(rc);
}
EXPORT_SYMBOL_GPL(uwb_rc_init);


struct uwb_rc *uwb_rc_alloc(void)
{
	struct uwb_rc *rc;
	rc = kzalloc(sizeof(*rc), GFP_KERNEL);
	if (rc == NULL)
		return NULL;
	uwb_rc_init(rc);
	return rc;
}
EXPORT_SYMBOL_GPL(uwb_rc_alloc);

/*
 * Show the ASIE that is broadcast in the UWB beacon by this uwb_rc device.
 */
static ssize_t ASIE_show(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	struct uwb_dev *uwb_dev = to_uwb_dev(dev);
	struct uwb_rc *rc = uwb_dev->rc;
	struct uwb_ie_hdr *ie;
	void *ptr;
	size_t len;
	int result = 0;

	/* init empty buffer. */
	result = scnprintf(buf, PAGE_SIZE, "\n");
	mutex_lock(&rc->ies_mutex);
	/* walk IEData looking for an ASIE. */
	ptr = rc->ies->IEData;
	len = le16_to_cpu(rc->ies->wIELength);
	for (;;) {
		ie = uwb_ie_next(&ptr, &len);
		if (!ie)
			break;
		if (ie->element_id == UWB_APP_SPEC_IE) {
			result = uwb_ie_dump_hex(ie,
					ie->length + sizeof(struct uwb_ie_hdr),
					buf, PAGE_SIZE);
			break;
		}
	}
	mutex_unlock(&rc->ies_mutex);

	return result;
}

/*
 * Update the ASIE that is broadcast in the UWB beacon by this uwb_rc device.
 */
static ssize_t ASIE_store(struct device *dev,
				 struct device_attribute *attr,
				 const char *buf, size_t size)
{
	struct uwb_dev *uwb_dev = to_uwb_dev(dev);
	struct uwb_rc *rc = uwb_dev->rc;
	char ie_buf[255];
	int result, ie_len = 0;
	const char *cur_ptr = buf;
	struct uwb_ie_hdr *ie;

	/* empty string means clear the ASIE. */
	if (strlen(buf) <= 1) {
		uwb_rc_ie_rm(rc, UWB_APP_SPEC_IE);
		return size;
	}

	/* if non-empty string, convert string of hex chars to binary. */
	while (ie_len < sizeof(ie_buf)) {
		int char_count;

		if (sscanf(cur_ptr, " %02hhX %n",
				&(ie_buf[ie_len]), &char_count) > 0) {
			++ie_len;
			/* skip chars read from cur_ptr. */
			cur_ptr += char_count;
		} else {
			break;
		}
	}

	/* validate IE length and type. */
	if (ie_len < sizeof(struct uwb_ie_hdr)) {
		dev_err(dev, "%s: Invalid ASIE size %d.\n", __func__, ie_len);
		return -EINVAL;
	}

	ie = (struct uwb_ie_hdr *)ie_buf;
	if (ie->element_id != UWB_APP_SPEC_IE) {
		dev_err(dev, "%s: Invalid IE element type size = 0x%02X.\n",
				__func__, ie->element_id);
		return -EINVAL;
	}

	/* bounds check length field from user. */
	if (ie->length > (ie_len - sizeof(struct uwb_ie_hdr)))
		ie->length = ie_len - sizeof(struct uwb_ie_hdr);

	/*
	 * Valid ASIE received. Remove current ASIE then add the new one using
	 * uwb_rc_ie_add.
	 */
	uwb_rc_ie_rm(rc, UWB_APP_SPEC_IE);

	result = uwb_rc_ie_add(rc, ie, ie->length + sizeof(struct uwb_ie_hdr));

	return result >= 0 ? size : result;
}
static DEVICE_ATTR_RW(ASIE);

static struct attribute *rc_attrs[] = {
		&dev_attr_mac_address.attr,
		&dev_attr_scan.attr,
		&dev_attr_beacon.attr,
		&dev_attr_ASIE.attr,
		NULL,
};

static struct attribute_group rc_attr_group = {
	.attrs = rc_attrs,
};

/*
 * Registration of sysfs specific stuff
 */
static int uwb_rc_sys_add(struct uwb_rc *rc)
{
	return sysfs_create_group(&rc->uwb_dev.dev.kobj, &rc_attr_group);
}


static void __uwb_rc_sys_rm(struct uwb_rc *rc)
{
	sysfs_remove_group(&rc->uwb_dev.dev.kobj, &rc_attr_group);
}

/**
 * uwb_rc_mac_addr_setup - get an RC's EUI-48 address or set it
 * @rc:  the radio controller.
 *
 * If the EUI-48 address is 00:00:00:00:00:00 or FF:FF:FF:FF:FF:FF
 * then a random locally administered EUI-48 is generated and set on
 * the device.  The probability of address collisions is sufficiently
 * unlikely (1/2^40 = 9.1e-13) that they're not checked for.
 */
static
int uwb_rc_mac_addr_setup(struct uwb_rc *rc)
{
	int result;
	struct device *dev = &rc->uwb_dev.dev;
	struct uwb_dev *uwb_dev = &rc->uwb_dev;
	char devname[UWB_ADDR_STRSIZE];
	struct uwb_mac_addr addr;

	result = uwb_rc_mac_addr_get(rc, &addr);
	if (result < 0) {
		dev_err(dev, "cannot retrieve UWB EUI-48 address: %d\n", result);
		return result;
	}

	if (uwb_mac_addr_unset(&addr) || uwb_mac_addr_bcast(&addr)) {
		addr.data[0] = 0x02; /* locally administered and unicast */
		get_random_bytes(&addr.data[1], sizeof(addr.data)-1);

		result = uwb_rc_mac_addr_set(rc, &addr);
		if (result < 0) {
			uwb_mac_addr_print(devname, sizeof(devname), &addr);
			dev_err(dev, "cannot set EUI-48 address %s: %d\n",
				devname, result);
			return result;
		}
	}
	uwb_dev->mac_addr = addr;
	return 0;
}



static int uwb_rc_setup(struct uwb_rc *rc)
{
	int result;
	struct device *dev = &rc->uwb_dev.dev;

	result = uwb_radio_setup(rc);
	if (result < 0) {
		dev_err(dev, "cannot setup UWB radio: %d\n", result);
		goto error;
	}
	result = uwb_rc_mac_addr_setup(rc);
	if (result < 0) {
		dev_err(dev, "cannot setup UWB MAC address: %d\n", result);
		goto error;
	}
	result = uwb_rc_dev_addr_assign(rc);
	if (result < 0) {
		dev_err(dev, "cannot assign UWB DevAddr: %d\n", result);
		goto error;
	}
	result = uwb_rc_ie_setup(rc);
	if (result < 0) {
		dev_err(dev, "cannot setup IE subsystem: %d\n", result);
		goto error_ie_setup;
	}
	result = uwb_rsv_setup(rc);
	if (result < 0) {
		dev_err(dev, "cannot setup reservation subsystem: %d\n", result);
		goto error_rsv_setup;
	}
	uwb_dbg_add_rc(rc);
	return 0;

error_rsv_setup:
	uwb_rc_ie_release(rc);
error_ie_setup:
error:
	return result;
}


/**
 * Register a new UWB radio controller
 *
 * Did you call uwb_rc_init() on your rc?
 *
 * We assume that this is being called with a > 0 refcount on
 * it [through ops->{get|put}_device(). We'll take our own, though.
 *
 * @parent_dev is our real device, the one that provides the actual UWB device
 */
int uwb_rc_add(struct uwb_rc *rc, struct device *parent_dev, void *priv)
{
	int result;
	struct device *dev;
	char macbuf[UWB_ADDR_STRSIZE], devbuf[UWB_ADDR_STRSIZE];

	rc->index = uwb_rc_new_index();

	dev = &rc->uwb_dev.dev;
	dev_set_name(dev, "uwb%d", rc->index);

	rc->priv = priv;

	init_waitqueue_head(&rc->uwbd.wq);
	INIT_LIST_HEAD(&rc->uwbd.event_list);
	spin_lock_init(&rc->uwbd.event_list_lock);

	uwbd_start(rc);

	result = rc->start(rc);
	if (result < 0)
		goto error_rc_start;

	result = uwb_rc_setup(rc);
	if (result < 0) {
		dev_err(dev, "cannot setup UWB radio controller: %d\n", result);
		goto error_rc_setup;
	}

	result = uwb_dev_add(&rc->uwb_dev, parent_dev, rc);
	if (result < 0 && result != -EADDRNOTAVAIL)
		goto error_dev_add;

	result = uwb_rc_sys_add(rc);
	if (result < 0) {
		dev_err(parent_dev, "cannot register UWB radio controller "
			"dev attributes: %d\n", result);
		goto error_sys_add;
	}

	uwb_mac_addr_print(macbuf, sizeof(macbuf), &rc->uwb_dev.mac_addr);
	uwb_dev_addr_print(devbuf, sizeof(devbuf), &rc->uwb_dev.dev_addr);
	dev_info(dev,
		 "new uwb radio controller (mac %s dev %s) on %s %s\n",
		 macbuf, devbuf, parent_dev->bus->name, dev_name(parent_dev));
	rc->ready = 1;
	return 0;

error_sys_add:
	uwb_dev_rm(&rc->uwb_dev);
error_dev_add:
error_rc_setup:
	rc->stop(rc);
error_rc_start:
	uwbd_stop(rc);
	return result;
}
EXPORT_SYMBOL_GPL(uwb_rc_add);


static int uwb_dev_offair_helper(struct device *dev, void *priv)
{
	struct uwb_dev *uwb_dev = to_uwb_dev(dev);

	return __uwb_dev_offair(uwb_dev, uwb_dev->rc);
}

/*
 * Remove a Radio Controller; stop beaconing/scanning, disconnect all children
 */
void uwb_rc_rm(struct uwb_rc *rc)
{
	rc->ready = 0;

	uwb_dbg_del_rc(rc);
	uwb_rsv_remove_all(rc);
	uwb_radio_shutdown(rc);

	rc->stop(rc);

	uwbd_stop(rc);
	uwb_rc_neh_destroy(rc);

	uwb_dev_lock(&rc->uwb_dev);
	rc->priv = NULL;
	rc->cmd = NULL;
	uwb_dev_unlock(&rc->uwb_dev);
	mutex_lock(&rc->uwb_beca.mutex);
	uwb_dev_for_each(rc, uwb_dev_offair_helper, NULL);
	__uwb_rc_sys_rm(rc);
	mutex_unlock(&rc->uwb_beca.mutex);
	uwb_rsv_cleanup(rc);
 	uwb_beca_release(rc);
	uwb_dev_rm(&rc->uwb_dev);
}
EXPORT_SYMBOL_GPL(uwb_rc_rm);

static int find_rc_try_get(struct device *dev, const void *data)
{
	const struct uwb_rc *target_rc = data;
	struct uwb_rc *rc = dev_get_drvdata(dev);

	if (rc == NULL) {
		WARN_ON(1);
		return 0;
	}
	if (rc == target_rc) {
		if (rc->ready == 0)
			return 0;
		else
			return 1;
	}
	return 0;
}

/**
 * Given a radio controller descriptor, validate and refcount it
 *
 * @returns NULL if the rc does not exist or is quiescing; the ptr to
 *               it otherwise.
 */
struct uwb_rc *__uwb_rc_try_get(struct uwb_rc *target_rc)
{
	struct device *dev;
	struct uwb_rc *rc = NULL;

	dev = class_find_device(&uwb_rc_class, NULL, target_rc,
				find_rc_try_get);
	if (dev) {
		rc = dev_get_drvdata(dev);
		__uwb_rc_get(rc);
		put_device(dev);
	}

	return rc;
}
EXPORT_SYMBOL_GPL(__uwb_rc_try_get);

/*
 * RC get for external refcount acquirers...
 *
 * Increments the refcount of the device and it's backend modules
 */
static inline struct uwb_rc *uwb_rc_get(struct uwb_rc *rc)
{
	if (rc->ready == 0)
		return NULL;
	uwb_dev_get(&rc->uwb_dev);
	return rc;
}

static int find_rc_grandpa(struct device *dev, const void *data)
{
	const struct device *grandpa_dev = data;
	struct uwb_rc *rc = dev_get_drvdata(dev);

	if (rc->uwb_dev.dev.parent->parent == grandpa_dev) {
		rc = uwb_rc_get(rc);
		return 1;
	}
	return 0;
}

/**
 * Locate and refcount a radio controller given a common grand-parent
 *
 * @grandpa_dev  Pointer to the 'grandparent' device structure.
 * @returns NULL If the rc does not exist or is quiescing; the ptr to
 *               it otherwise, properly referenced.
 *
 * The Radio Control interface (or the UWB Radio Controller) is always
 * an interface of a device. The parent is the interface, the
 * grandparent is the device that encapsulates the interface.
 *
 * There is no need to lock around as the "grandpa" would be
 * refcounted by the target, and to remove the referemes, the
 * uwb_rc_class->sem would have to be taken--we hold it, ergo we
 * should be safe.
 */
struct uwb_rc *uwb_rc_get_by_grandpa(const struct device *grandpa_dev)
{
	struct device *dev;
	struct uwb_rc *rc = NULL;

	dev = class_find_device(&uwb_rc_class, NULL, grandpa_dev,
				find_rc_grandpa);
	if (dev) {
		rc = dev_get_drvdata(dev);
		put_device(dev);
	}

	return rc;
}
EXPORT_SYMBOL_GPL(uwb_rc_get_by_grandpa);

/**
 * Find a radio controller by device address
 *
 * @returns the pointer to the radio controller, properly referenced
 */
static int find_rc_dev(struct device *dev, const void *data)
{
	const struct uwb_dev_addr *addr = data;
	struct uwb_rc *rc = dev_get_drvdata(dev);

	if (rc == NULL) {
		WARN_ON(1);
		return 0;
	}
	if (!uwb_dev_addr_cmp(&rc->uwb_dev.dev_addr, addr)) {
		rc = uwb_rc_get(rc);
		return 1;
	}
	return 0;
}

struct uwb_rc *uwb_rc_get_by_dev(const struct uwb_dev_addr *addr)
{
	struct device *dev;
	struct uwb_rc *rc = NULL;

	dev = class_find_device(&uwb_rc_class, NULL, addr, find_rc_dev);
	if (dev) {
		rc = dev_get_drvdata(dev);
		put_device(dev);
	}

	return rc;
}
EXPORT_SYMBOL_GPL(uwb_rc_get_by_dev);

/**
 * Drop a reference on a radio controller
 *
 * This is the version that should be done by entities external to the
 * UWB Radio Control stack (ie: clients of the API).
 */
void uwb_rc_put(struct uwb_rc *rc)
{
	__uwb_rc_put(rc);
}
EXPORT_SYMBOL_GPL(uwb_rc_put);
