/*
 * This file is part of the UWB stack for linux.
 *
 * Copyright (c) 2020-2021 Qorvo US, Inc.
 *
 * This software is provided under the GNU General Public License, version 2
 * (GPLv2), as well as under a Qorvo commercial license.
 *
 * You may choose to use this software under the terms of the GPLv2 License,
 * version 2 ("GPLv2"), as published by the Free Software Foundation.
 * You should have received a copy of the GPLv2 along with this program.  If
 * not, see <http://www.gnu.org/licenses/>.
 *
 * This program is distributed under the GPLv2 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 GPLv2 for more
 * details.
 *
 * If you cannot meet the requirements of the GPLv2, you may not use this
 * software for any purpose without first obtaining a commercial license from
 * Qorvo. Please contact Qorvo to inquire about licensing terms.
 */

#include "nfcc_coex_access.h"
#include "nfcc_coex_session.h"
#include "nfcc_coex_region.h"
#include "llhw-ops.h"

#include <linux/string.h>
#include <linux/ieee802154.h>
#include <net/mcps802154_frame.h>
#include <net/vendor_cmd.h>

#include "warn_return.h"

static void nfcc_coex_stop_by_vendor_cmd_failure(struct nfcc_coex_local *local)
{
	static const struct dw3000_vendor_cmd_nfcc_coex_get_access_info error = {
		.stop = 1
	};

	local->session.get_access_info = error;
	local->state = NFCC_COEX_STATE_STOPPING;
}

static int nfcc_coex_vendor_cmd(struct mcps802154_llhw *llhw,
				enum dw3000_vendor_cmd subcmd, void *data,
				size_t data_len)
{
	struct mcps802154_local *local = llhw_to_local(llhw);
	/* Qorvo OUI in big endian. */
	static const u32 qorvo_oui = 0xc8b1ee00;

	return llhw_vendor_cmd(local, qorvo_oui, subcmd, data, data_len);
}

static void nfcc_coex_access_done(struct mcps802154_access *access, int error)
{
	struct nfcc_coex_local *local = access_to_local(access);
	struct nfcc_coex_session *session = &local->session;

	switch (local->state) {
	case NFCC_COEX_STATE_STOPPING:
		nfcc_coex_vendor_cmd(local->llhw,
				     DW3000_VENDOR_CMD_NFCC_COEX_STOP, NULL, 0);
		nfcc_coex_report(local);
		break;
	case NFCC_COEX_STATE_ACCESSING:
		if (session->get_access_info.stop ||
		    session->get_access_info.watchdog_timeout)
			local->state = NFCC_COEX_STATE_STOPPING;
		nfcc_coex_report(local);
		break;
	default:
		WARN_UNREACHABLE_DEFAULT();
	}
}

static int nfcc_coex_handle(struct mcps802154_access *access)
{
	struct nfcc_coex_local *local = access_to_local(access);
	struct nfcc_coex_session *session = &local->session;
	struct dw3000_vendor_cmd_nfcc_coex_handle_access handle_access = {};
	int r;

	handle_access.start = session->first_access;
	handle_access.timestamp_dtu = access->timestamp_dtu;
	handle_access.duration_dtu = access->duration_dtu;
	handle_access.chan = session->params.channel_number;

	session->first_access = false;

	r = nfcc_coex_vendor_cmd(local->llhw,
				 DW3000_VENDOR_CMD_NFCC_COEX_HANDLE_ACCESS,
				 &handle_access, sizeof(handle_access));
	if (r)
		nfcc_coex_stop_by_vendor_cmd_failure(local);
	return r;
}

static int nfcc_coex_tx_done(struct mcps802154_access *access)
{
	struct nfcc_coex_local *local = access_to_local(access);
	struct nfcc_coex_session *session = &local->session;
	struct dw3000_vendor_cmd_nfcc_coex_get_access_info *get_access_info =
		&session->get_access_info;
	struct mcps802154_region_demand *rd = &session->region_demand;
	int r;

	r = nfcc_coex_vendor_cmd(
		local->llhw, DW3000_VENDOR_CMD_NFCC_COEX_GET_ACCESS_INFORMATION,
		get_access_info, sizeof(*get_access_info));
	if (r) {
		nfcc_coex_stop_by_vendor_cmd_failure(local);
		return r;
	}

	rd->timestamp_dtu = get_access_info->next_timestamp_dtu;
	rd->duration_dtu = get_access_info->next_duration_dtu;

	/* Request end of current access. */
	return 1;
}

struct mcps802154_access_vendor_ops nfcc_coex_ops = {
	.common = {
		.access_done = nfcc_coex_access_done,
	},
	.handle = nfcc_coex_handle,
	.tx_done = nfcc_coex_tx_done,
};

static struct mcps802154_access *
nfcc_coex_access_controller(struct nfcc_coex_local *local,
			    struct nfcc_coex_session *session)
{
	struct mcps802154_access *access = &local->access;

	access->method = MCPS802154_ACCESS_METHOD_VENDOR;
	access->vendor_ops = &nfcc_coex_ops;
	access->duration_dtu = session->region_demand.duration_dtu;
	access->timestamp_dtu = session->region_demand.timestamp_dtu;
	access->n_frames = 0;
	access->frames = NULL;

	return access;
}

struct mcps802154_access *nfcc_coex_get_access(struct mcps802154_region *region,
					       u32 next_timestamp_dtu,
					       int next_in_region_dtu,
					       int region_duration_dtu)
{
	struct nfcc_coex_local *local = region_to_local(region);
	struct nfcc_coex_session *session;

	/* Get unique session. */
	session = nfcc_coex_session_next(local, next_timestamp_dtu,
					 region_duration_dtu);

	if (!session) {
		local->state = NFCC_COEX_STATE_UNUSED;
		return NULL;
	} else {
		local->state = NFCC_COEX_STATE_ACCESSING;
		return nfcc_coex_access_controller(local, session);
	}
}
