/*
 * Ultra Wide Band
 * UWB basic command support and radio reset
 *
 * 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
 *
 *  - Now we are serializing (using the uwb_dev->mutex) the command
 *    execution; it should be parallelized as much as possible some
 *    day.
 */
#include <linux/kernel.h>
#include <linux/err.h>

#include "uwb-internal.h"
#define D_LOCAL 0
#include <linux/uwb/debug.h>

/**
 * Command result codes (WUSB1.0[T8-69])
 */
static
const char *__strerror[] = {
	"success",
	"failure",
	"hardware failure",
	"no more slots",
	"beacon is too large",
	"invalid parameter",
	"unsupported power level",
	"time out (wa) or invalid ie data (whci)",
	"beacon size exceeded",
	"cancelled",
	"invalid state",
	"invalid size",
	"ack not recieved",
	"no more asie notification",
};


/** Return a string matching the given error code */
const char *uwb_rc_strerror(unsigned code)
{
	if (code == 255)
		return "time out";
	if (code >= ARRAY_SIZE(__strerror))
		return "unknown error";
	return __strerror[code];
}

int uwb_rc_cmd_async(struct uwb_rc *rc, const char *cmd_name,
		     struct uwb_rccb *cmd, size_t cmd_size,
		     u8 expected_type, u16 expected_event,
		     uwb_rc_cmd_cb_f cb, void *arg)
{
	struct device *dev = &rc->uwb_dev.dev;
	struct uwb_rc_neh *neh;
	int needtofree = 0;
	int result;

	uwb_dev_lock(&rc->uwb_dev);	/* Protect against rc->priv being removed */
	if (rc->priv == NULL) {
		uwb_dev_unlock(&rc->uwb_dev);
		return -ESHUTDOWN;
	}

	if (rc->filter_cmd) {
		needtofree = rc->filter_cmd(rc, &cmd, &cmd_size);
		if (needtofree < 0 && needtofree != -ENOANO) {
			dev_err(dev, "%s: filter error: %d\n",
				cmd_name, needtofree);
			uwb_dev_unlock(&rc->uwb_dev);
			return needtofree;
		}
	}

	neh = uwb_rc_neh_add(rc, cmd, expected_type, expected_event, cb, arg);
	if (IS_ERR(neh)) {
		result = PTR_ERR(neh);
		goto out;
	}

	result = rc->cmd(rc, cmd, cmd_size);
	uwb_dev_unlock(&rc->uwb_dev);
	if (result < 0)
		uwb_rc_neh_rm(rc, neh);
	else
		uwb_rc_neh_arm(rc, neh);
	uwb_rc_neh_put(neh);
out:
	if (needtofree == 1)
		kfree(cmd);
	return result < 0 ? result : 0;
}
EXPORT_SYMBOL_GPL(uwb_rc_cmd_async);

struct uwb_rc_cmd_done_params {
	struct completion completion;
	struct uwb_rceb *reply;
	ssize_t reply_size;
};

static void uwb_rc_cmd_done(struct uwb_rc *rc, void *arg,
			    struct uwb_rceb *reply, ssize_t reply_size)
{
	struct uwb_rc_cmd_done_params *p = (struct uwb_rc_cmd_done_params *)arg;

	if (reply_size > 0) {
		if (p->reply)
			reply_size = min(p->reply_size, reply_size);
		else
			p->reply = kmalloc(reply_size, GFP_ATOMIC);

		if (p->reply)
			memcpy(p->reply, reply, reply_size);
		else
			reply_size = -ENOMEM;
	}
	p->reply_size = reply_size;
	complete(&p->completion);
}


/**
 * Generic function for issuing commands to the Radio Control Interface
 *
 * @rc:       UWB Radio Control descriptor
 * @cmd_name: Name of the command being issued (for error messages)
 * @cmd:      Pointer to rccb structure containing the command;
 *            normally you embed this structure as the first member of
 *            the full command structure.
 * @cmd_size: Size of the whole command buffer pointed to by @cmd.
 * @reply:    Pointer to where to store the reply
 * @reply_size: @reply's size
 * @expected_type: Expected type in the return event
 * @expected_event: Expected event code in the return event
 * @preply:   Here a pointer to where the event data is received will
 *            be stored. Once done with the data, free with kfree().
 *
 * This function is generic; it works for commands that return a fixed
 * and known size or for commands that return a variable amount of data.
 *
 * If a buffer is provided, that is used, although it could be chopped
 * to the maximum size of the buffer. If the buffer is NULL, then one
 * be allocated in *preply with the whole contents of the reply.
 *
 * @rc needs to be referenced
 */
static
ssize_t __uwb_rc_cmd(struct uwb_rc *rc, const char *cmd_name,
		     struct uwb_rccb *cmd, size_t cmd_size,
		     struct uwb_rceb *reply, size_t reply_size,
		     u8 expected_type, u16 expected_event,
		     struct uwb_rceb **preply)
{
	ssize_t result = 0;
	struct device *dev = &rc->uwb_dev.dev;
	struct uwb_rc_cmd_done_params params;

	init_completion(&params.completion);
	params.reply = reply;
	params.reply_size = reply_size;

	result = uwb_rc_cmd_async(rc, cmd_name, cmd, cmd_size,
				  expected_type, expected_event,
				  uwb_rc_cmd_done, &params);
	if (result)
		return result;

	wait_for_completion(&params.completion);

	if (preply)
		*preply = params.reply;

	if (params.reply_size < 0)
		dev_err(dev, "%s: confirmation event 0x%02x/%04x/%02x "
			"reception failed: %d\n", cmd_name,
			expected_type, expected_event, cmd->bCommandContext,
			(int)params.reply_size);
	return params.reply_size;
}


/**
 * Generic function for issuing commands to the Radio Control Interface
 *
 * @rc:       UWB Radio Control descriptor
 * @cmd_name: Name of the command being issued (for error messages)
 * @cmd:      Pointer to rccb structure containing the command;
 *            normally you embed this structure as the first member of
 *            the full command structure.
 * @cmd_size: Size of the whole command buffer pointed to by @cmd.
 * @reply:    Pointer to the beginning of the confirmation event
 *            buffer. Normally bigger than an 'struct hwarc_rceb'.
 *            You need to fill out reply->bEventType and reply->wEvent (in
 *            cpu order) as the function will use them to verify the
 *            confirmation event.
 * @reply_size: Size of the reply buffer
 *
 * The function checks that the length returned in the reply is at
 * least as big as @reply_size; if not, it will be deemed an error and
 * -EIO returned.
 *
 * @rc needs to be referenced
 */
ssize_t uwb_rc_cmd(struct uwb_rc *rc, const char *cmd_name,
		   struct uwb_rccb *cmd, size_t cmd_size,
		   struct uwb_rceb *reply, size_t reply_size)
{
	struct device *dev = &rc->uwb_dev.dev;
	ssize_t result;

	result = __uwb_rc_cmd(rc, cmd_name,
			      cmd, cmd_size, reply, reply_size,
			      reply->bEventType, reply->wEvent, NULL);

	if (result > 0 && result < reply_size) {
		dev_err(dev, "%s: not enough data returned for decoding reply "
			"(%zu bytes received vs at least %zu needed)\n",
			cmd_name, result, reply_size);
		result = -EIO;
	}
	return result;
}
EXPORT_SYMBOL_GPL(uwb_rc_cmd);


/**
 * Generic function for issuing commands to the Radio Control
 * Interface that return an unknown amount of data
 *
 * @rc:       UWB Radio Control descriptor
 * @cmd_name: Name of the command being issued (for error messages)
 * @cmd:      Pointer to rccb structure containing the command;
 *            normally you embed this structure as the first member of
 *            the full command structure.
 * @cmd_size: Size of the whole command buffer pointed to by @cmd.
 * @expected_type: Expected type in the return event
 * @expected_event: Expected event code in the return event
 * @preply:   Here a pointer to where the event data is received will
 *            be stored. Once done with the data, free with kfree().
 *
 * The function checks that the length returned in the reply is at
 * least as big as a 'struct uwb_rceb *'; if not, it will be deemed an
 * error and -EIO returned.
 *
 * @rc needs to be referenced
 */
ssize_t uwb_rc_vcmd(struct uwb_rc *rc, const char *cmd_name,
		    struct uwb_rccb *cmd, size_t cmd_size,
		    u8 expected_type, u16 expected_event,
		    struct uwb_rceb **preply)
{
	return __uwb_rc_cmd(rc, cmd_name, cmd, cmd_size, NULL, 0,
			    expected_type, expected_event, preply);
}
EXPORT_SYMBOL_GPL(uwb_rc_vcmd);


/**
 * Reset a UWB Host Controller (and all radio settings)
 *
 * @rc:      Host Controller descriptor
 * @returns: 0 if ok, < 0 errno code on error
 *
 * We put the command on kmalloc'ed memory as some arches cannot do
 * USB from the stack. The reply event is copied from an stage buffer,
 * so it can be in the stack. See WUSB1.0[8.6.2.4] for more details.
 */
int uwb_rc_reset(struct uwb_rc *rc)
{
	int result = -ENOMEM;
	struct uwb_rc_evt_confirm reply;
	struct uwb_rccb *cmd;
	size_t cmd_size = sizeof(*cmd);

	mutex_lock(&rc->uwb_dev.mutex);
	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
	if (cmd == NULL)
		goto error_kzalloc;
	cmd->bCommandType = UWB_RC_CET_GENERAL;
	cmd->wCommand = cpu_to_le16(UWB_RC_CMD_RESET);
	reply.rceb.bEventType = UWB_RC_CET_GENERAL;
	reply.rceb.wEvent = UWB_RC_CMD_RESET;
	result = uwb_rc_cmd(rc, "RESET", cmd, cmd_size,
			    &reply.rceb, sizeof(reply));
	if (result < 0)
		goto error_cmd;
	if (reply.bResultCode != UWB_RC_RES_SUCCESS) {
		dev_err(&rc->uwb_dev.dev,
			"RESET: command execution failed: %s (%d)\n",
			uwb_rc_strerror(reply.bResultCode), reply.bResultCode);
		result = -EIO;
	}
error_cmd:
	kfree(cmd);
error_kzalloc:
	mutex_unlock(&rc->uwb_dev.mutex);
	return result;
}

int uwbd_msg_handle_reset(struct uwb_event *evt)
{
	struct uwb_rc *rc = evt->rc;
	int ret;

	/* Need to prevent the RC hardware module going away while in
	   the rc->reset() call. */
	if (!try_module_get(rc->owner))
		return 0;

	dev_info(&rc->uwb_dev.dev, "resetting radio controller\n");
	ret = rc->reset(rc);
	if (ret)
		dev_err(&rc->uwb_dev.dev, "failed to reset hardware: %d\n", ret);

	module_put(rc->owner);
	return ret;
}

/**
 * uwb_rc_reset_all - request a reset of the radio controller and PALs
 * @rc: the radio controller of the hardware device to be reset.
 *
 * The full hardware reset of the radio controller and all the PALs
 * will be scheduled.
 */
void uwb_rc_reset_all(struct uwb_rc *rc)
{
	struct uwb_event *evt;

	evt = kzalloc(sizeof(struct uwb_event), GFP_ATOMIC);
	if (unlikely(evt == NULL))
		return;

	evt->rc = __uwb_rc_get(rc);	/* will be put by uwbd's uwbd_event_handle() */
	evt->ts_jiffies = jiffies;
	evt->type = UWB_EVT_TYPE_MSG;
	evt->message = UWB_EVT_MSG_RESET;

	uwbd_event_queue(evt);
}
EXPORT_SYMBOL_GPL(uwb_rc_reset_all);
