/*
 * 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 <linux/errno.h>

#include "mcps802154_i.h"

static void
mcps802154_fproc_vendor_handle_callback_return(struct mcps802154_local *local,
					       int r)
{
	struct mcps802154_access *access = local->fproc.access;
	/* Fetch/copy needed data before access_done.
	 * Avoid usage of access pointer after access done call. */
	int duration_dtu = access->duration_dtu;
	u32 next_access_dtu = access->timestamp_dtu + duration_dtu;

	if (!r)
		/* TODO_MR : call access_done(false) ?? */
		return;

	mcps802154_fproc_access_done(local, r);
	if (r != 1) {
		mcps802154_fproc_broken_handle(local);
	} else if (duration_dtu) {
		mcps802154_fproc_access(local, next_access_dtu);
	} else {
		mcps802154_fproc_access_now(local);
	}
}

static void mcps802154_fproc_vendor_rx_frame(struct mcps802154_local *local)
{
	struct mcps802154_access *access = local->fproc.access;
	int r;

	if (access->vendor_ops->rx_frame)
		r = access->vendor_ops->rx_frame(access);
	else
		r = -EOPNOTSUPP;
	mcps802154_fproc_vendor_handle_callback_return(local, r);
}

static void mcps802154_fproc_vendor_rx_timeout(struct mcps802154_local *local)
{
	struct mcps802154_access *access = local->fproc.access;
	int r;

	if (access->vendor_ops->rx_timeout)
		r = access->vendor_ops->rx_timeout(access);
	else
		r = -EOPNOTSUPP;
	mcps802154_fproc_vendor_handle_callback_return(local, r);
}

static void
mcps802154_fproc_vendor_rx_error(struct mcps802154_local *local,
				 enum mcps802154_rx_error_type error)
{
	struct mcps802154_access *access = local->fproc.access;
	int r;

	if (access->vendor_ops->rx_error)
		r = access->vendor_ops->rx_error(access, error);
	else
		r = -EOPNOTSUPP;
	mcps802154_fproc_vendor_handle_callback_return(local, r);
}

static void mcps802154_fproc_vendor_tx_done(struct mcps802154_local *local)
{
	struct mcps802154_access *access = local->fproc.access;
	int r;

	if (access->vendor_ops->tx_done)
		r = access->vendor_ops->tx_done(access);
	else
		r = EOPNOTSUPP;
	mcps802154_fproc_vendor_handle_callback_return(local, r);
}

static void mcps802154_fproc_vendor_broken(struct mcps802154_local *local)
{
	struct mcps802154_access *access = local->fproc.access;
	int r;

	if (access->vendor_ops->broken)
		r = access->vendor_ops->broken(access);
	else
		r = -EOPNOTSUPP;
	mcps802154_fproc_vendor_handle_callback_return(local, r);
}

static void
mcps802154_fproc_vendor_timer_expired(struct mcps802154_local *local)
{
	struct mcps802154_access *access = local->fproc.access;

	if (access->vendor_ops->timer_expired) {
		int r;

		r = access->vendor_ops->timer_expired(access);
		mcps802154_fproc_vendor_handle_callback_return(local, r);
	}
}

static void
mcps802154_fproc_vendor_schedule_change(struct mcps802154_local *local)
{
	struct mcps802154_access *access = local->fproc.access;

	if (access->vendor_ops->schedule_change) {
		int r;

		r = access->vendor_ops->schedule_change(access);
		mcps802154_fproc_vendor_handle_callback_return(local, r);
	}
}

static const struct mcps802154_fproc_state mcps802154_fproc_vendor = {
	.name = "vendor",
	.rx_frame = mcps802154_fproc_vendor_rx_frame,
	.rx_timeout = mcps802154_fproc_vendor_rx_timeout,
	.rx_error = mcps802154_fproc_vendor_rx_error,
	.tx_done = mcps802154_fproc_vendor_tx_done,
	.broken = mcps802154_fproc_vendor_broken,
	.timer_expired = mcps802154_fproc_vendor_timer_expired,
	.schedule_change = mcps802154_fproc_vendor_schedule_change,
};

int mcps802154_fproc_vendor_handle(struct mcps802154_local *local,
				   struct mcps802154_access *access)
{
	mcps802154_fproc_change_state(local, &mcps802154_fproc_vendor);

	if (access->vendor_ops->handle) {
		return access->vendor_ops->handle(access);
	}
	return 0;
}
