/*
 * 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 "uwb-internal.h"

static int uwb_rc_index_match(struct device *dev, void *data)
{
	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);
	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);

static struct attribute *rc_attrs[] = {
		&dev_attr_mac_address.attr,
		&dev_attr_scan.attr,
		&dev_attr_beacon.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, void *data)
{
	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);
	}
	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, void *data)
{
	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, (void *)grandpa_dev,
				find_rc_grandpa);
	if (dev)
		rc = dev_get_drvdata(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, void *data)
{
	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, (void *)addr,
				find_rc_dev);
	if (dev)
		rc = dev_get_drvdata(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);
