/*
 * 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/slab.h>
#include <linux/errno.h>
#include <linux/math64.h>

#include <linux/netdevice.h>

#include <net/mcps802154_schedule.h>
#include <net/fira_region_nl.h>

#include "fira_region.h"
#include "fira_region_call.h"
#include "fira_access.h"
#include "fira_session.h"

#include "warn_return.h"

static struct mcps802154_region_ops fira_region_ops;

static struct mcps802154_region *fira_open(struct mcps802154_llhw *llhw)
{
	struct fira_local *local;

	local = kmalloc(sizeof(*local), GFP_KERNEL);
	if (!local)
		return NULL;
	local->llhw = llhw;
	local->region.ops = &fira_region_ops;
	INIT_LIST_HEAD(&local->inactive_sessions);
	INIT_LIST_HEAD(&local->active_sessions);
	local->block_duration_rx_margin_ppm = UWB_BLOCK_DURATION_MARGIN_PPM;
	return &local->region;
}

static void fira_close(struct mcps802154_region *region)
{
	struct fira_local *local = region_to_local(region);

	kfree_sensitive(local);
}

static void fira_notify_stop(struct mcps802154_region *region)
{
	struct fira_local *local = region_to_local(region);
	struct fira_session *session, *s;

	list_for_each_entry_safe (session, s, &local->active_sessions, entry) {
		session->stop_request = true;
		fira_session_access_done(local, session, false);
	}
}

static int fira_call(struct mcps802154_region *region, u32 call_id,
		     const struct nlattr *attrs, const struct genl_info *info)
{
	struct fira_local *local = region_to_local(region);

	switch (call_id) {
	case FIRA_CALL_GET_CAPABILITIES:
		return fira_get_capabilities(local, info);
	case FIRA_CALL_SESSION_INIT:
	case FIRA_CALL_SESSION_START:
	case FIRA_CALL_SESSION_STOP:
	case FIRA_CALL_SESSION_DEINIT:
	case FIRA_CALL_SESSION_SET_PARAMS:
	case FIRA_CALL_SESSION_GET_STATE:
	case FIRA_CALL_SESSION_GET_COUNT:
	case FIRA_CALL_NEW_CONTROLEE:
	case FIRA_CALL_DEL_CONTROLEE:
	case FIRA_CALL_SESSION_GET_PARAMS:
		return fira_session_control(local, call_id, attrs, info);
	default:
		return -EINVAL;
	}
}

static int fira_get_demand(struct mcps802154_region *region,
			   u32 next_timestamp_dtu,
			   struct mcps802154_region_demand *demand)
{
	struct fira_local *local = region_to_local(region);
	struct fira_session *session;

	session = fira_session_next(
		local, next_timestamp_dtu + local->llhw->anticip_dtu, 0);

	if (session) {
		fira_session_get_demand(local, session, demand);
		demand->duration_dtu = session->last_access_duration_dtu;
		local->current_session = session;
		return 1;
	}
	return 0;
}

static int fira_report_local_aoa(struct fira_local *local, struct sk_buff *msg,
				 const struct fira_local_aoa_info *info)
{
#define A(x) FIRA_RANGING_DATA_MEASUREMENTS_AOA_ATTR_##x
	if (nla_put_u8(msg, A(RX_ANTENNA_PAIR), info->rx_ant_pair))
		goto nla_put_failure;
	if (nla_put_s16(msg, A(AOA_2PI), info->aoa_2pi))
		goto nla_put_failure;
	if (nla_put_s16(msg, A(PDOA_2PI), info->pdoa_2pi))
		goto nla_put_failure;
	if (nla_put_u8(msg, A(AOA_FOM), info->aoa_fom))
		goto nla_put_failure;
#undef A
	return 0;
nla_put_failure:
	return -EMSGSIZE;
}

static int fira_report_measurement(struct fira_local *local,
				   struct sk_buff *msg,
				   const struct fira_ranging_info *ranging_info)
{
	const struct fira_session *session = local->current_session;
	struct nlattr *aoa;
#define A(x) FIRA_RANGING_DATA_MEASUREMENTS_ATTR_##x

	if (nla_put_u16(msg, A(SHORT_ADDR), ranging_info->short_addr) ||
	    nla_put_u8(msg, A(STATUS), ranging_info->status))
		goto nla_put_failure;

	if (ranging_info->status) {
		if (nla_put_u8(msg, A(SLOT_INDEX), ranging_info->slot_index))
			goto nla_put_failure;
		return 0;
	}

	if (ranging_info->tof_present) {
		static const s64 speed_of_light_mm_per_s = 299702547000ull;
		s32 distance_mm = div64_s64(
			ranging_info->tof_rctu * speed_of_light_mm_per_s,
			(s64)local->llhw->dtu_freq_hz * local->llhw->dtu_rctu);
		if (nla_put_s32(msg, A(DISTANCE_MM), distance_mm))
			goto nla_put_failure;
	}

	if (ranging_info->local_aoa.present) {
		aoa = nla_nest_start(msg, A(LOCAL_AOA));
		if (!aoa)
			goto nla_put_failure;
		if (fira_report_local_aoa(local, msg, &ranging_info->local_aoa))
			goto nla_put_failure;
		nla_nest_end(msg, aoa);
	}
	if (ranging_info->local_aoa_azimuth.present) {
		aoa = nla_nest_start(msg, A(LOCAL_AOA_AZIMUTH));
		if (!aoa)
			goto nla_put_failure;
		if (fira_report_local_aoa(local, msg,
					  &ranging_info->local_aoa_azimuth))
			goto nla_put_failure;
		nla_nest_end(msg, aoa);
	}
	if (ranging_info->local_aoa_elevation.present) {
		aoa = nla_nest_start(msg, A(LOCAL_AOA_ELEVATION));
		if (!aoa)
			goto nla_put_failure;
		if (fira_report_local_aoa(local, msg,
					  &ranging_info->local_aoa_elevation))
			goto nla_put_failure;
		nla_nest_end(msg, aoa);
	}
	if (ranging_info->remote_aoa_azimuth_present) {
		if (nla_put_s16(msg, A(REMOTE_AOA_AZIMUTH_2PI),
				ranging_info->remote_aoa_azimuth_2pi))
			goto nla_put_failure;
		if (ranging_info->remote_aoa_fom_present) {
			if (nla_put_u8(msg, A(REMOTE_AOA_AZIMUTH_FOM),
				       ranging_info->remote_aoa_azimuth_fom))
				goto nla_put_failure;
		}
	}
	if (ranging_info->remote_aoa_elevation_present) {
		if (nla_put_s16(msg, A(REMOTE_AOA_ELEVATION_PI),
				ranging_info->remote_aoa_elevation_pi))
			goto nla_put_failure;
		if (ranging_info->remote_aoa_fom_present) {
			if (nla_put_u8(msg, A(REMOTE_AOA_ELEVATION_FOM),
				       ranging_info->remote_aoa_elevation_fom))
				goto nla_put_failure;
		}
	}
	if (ranging_info->data_payload_len > 0) {
		if (nla_put(msg, A(DATA_PAYLOAD_RECV),
			    ranging_info->data_payload_len,
			    ranging_info->data_payload))
			goto nla_put_failure;
	}
	if (session->data_payload_seq_sent > 0) {
		if (nla_put_u32(msg, A(DATA_PAYLOAD_SEQ_SENT),
				session->data_payload_seq_sent))
			goto nla_put_failure;
	}

#undef A
	return 0;
nla_put_failure:
	return -EMSGSIZE;
}

static int fira_report_measurement_stopped_controlee(struct fira_local *local,
						     struct sk_buff *msg,
						     __le16 short_addr)
{
#define A(x) FIRA_RANGING_DATA_MEASUREMENTS_ATTR_##x

	if (nla_put_u16(msg, A(SHORT_ADDR), short_addr) ||
	    nla_put_u8(msg, A(STOPPED), 1))
		goto nla_put_failure;

#undef A
	return 0;
nla_put_failure:
	return -EMSGSIZE;
}

void fira_report(struct fira_local *local, struct fira_session *session,
		 bool add_measurements)
{
	struct sk_buff *msg;
	struct nlattr *data, *measurements, *measurement;
	int block_duration_ms, i, r;
	bool stop_completed;

	msg = mcps802154_region_event_alloc_skb(local->llhw, &local->region,
						FIRA_CALL_SESSION_NOTIFICATION,
						session->event_portid,
						NLMSG_DEFAULT_SIZE, GFP_KERNEL);
	if (!msg)
		return;

	if (nla_put_u32(msg, FIRA_CALL_ATTR_SESSION_ID, session->id))
		goto nla_put_failure;

	data = nla_nest_start(msg, FIRA_CALL_ATTR_RANGING_DATA);
	if (!data)
		goto nla_put_failure;

	block_duration_ms = session->params.block_duration_dtu /
			    (local->llhw->dtu_freq_hz / 1000);
	if (nla_put_u32(msg, FIRA_RANGING_DATA_ATTR_BLOCK_INDEX,
			session->block_index) ||
	    nla_put_u32(msg, FIRA_RANGING_DATA_ATTR_RANGING_INTERVAL_MS,
			block_duration_ms))
		goto nla_put_failure;

	stop_completed = session->stop_request &&
			 !(session->controlee_management_flags &
			   FIRA_SESSION_CONTROLEE_MANAGEMENT_FLAG_STOP);
	if (stop_completed || session->stop_inband ||
	    session->stop_no_response) {
		enum fira_ranging_data_attrs_stopped_values stopped_value =
			stop_completed ?
				FIRA_RANGING_DATA_ATTR_STOPPED_REQUEST :
				session->stop_inband ?
				FIRA_RANGING_DATA_ATTR_STOPPED_IN_BAND :
				FIRA_RANGING_DATA_ATTR_STOPPED_NO_RESPONSE;

		if (nla_put_u8(msg, FIRA_RANGING_DATA_ATTR_STOPPED,
			       stopped_value))
			goto nla_put_failure;
	}

	if (add_measurements && (local->n_ranging_info +
				 local->n_stopped_controlees_short_addr) != 0) {
		measurements = nla_nest_start(
			msg, FIRA_RANGING_DATA_ATTR_MEASUREMENTS);
		if (!measurements)
			goto nla_put_failure;

		for (i = 0; i < local->n_ranging_info; i++) {
			measurement = nla_nest_start(msg, 1);
			if (fira_report_measurement(local, msg,
						    &local->ranging_info[i]))
				goto nla_put_failure;
			nla_nest_end(msg, measurement);
		}

		for (i = 0; i < local->n_stopped_controlees_short_addr; i++) {
			measurement = nla_nest_start(msg, 1);
			if (fira_report_measurement_stopped_controlee(
				    local, msg,
				    local->stopped_controlees_short_addr[i]))
				goto nla_put_failure;
			nla_nest_end(msg, measurement);
		}

		nla_nest_end(msg, measurements);
	}

	nla_nest_end(msg, data);

	r = mcps802154_region_event(local->llhw, msg);
	if (r == -ECONNREFUSED)
		/* TODO stop. */
		;
	return;
nla_put_failure:
	kfree_skb(msg);
}

void fira_session_notify_state_change(struct fira_local *local, u32 session_id, uint8_t state)
{
	int r;
	static struct sk_buff *msg;

	/* TODO: reenable when state notification supported by the HAL */
	return;

	msg = mcps802154_region_call_alloc_reply_skb(
			local->llhw, &local->region, FIRA_CALL_SESSION_STATE_NOTIFICATION,
			NLMSG_DEFAULT_SIZE);
	if (!msg)
		return;

	if (nla_put_u32(msg, FIRA_CALL_ATTR_SESSION_ID, session_id))
		goto nla_put_failure;

	if (nla_put_u8(msg, FIRA_CALL_ATTR_SESSION_STATE, state))
		goto nla_put_failure;

	r = mcps802154_region_call_reply(local->llhw, msg);
	if (r == -ECONNREFUSED)
		/* TODO stop. */
		;
	return;
nla_put_failure:
	kfree_skb(msg);
}

static struct mcps802154_region_ops fira_region_ops = {
	.owner = THIS_MODULE,
	.name = "fira",
	.open = fira_open,
	.close = fira_close,
	.notify_stop = fira_notify_stop,
	.call = fira_call,
	.get_access = fira_get_access,
	.get_demand = fira_get_demand,
};

int __init fira_region_init(void)
{
	int r;

	r = fira_crypto_test();
	WARN_RETURN(r);

	return mcps802154_region_register(&fira_region_ops);
}

void __exit fira_region_exit(void)
{
	mcps802154_region_unregister(&fira_region_ops);
}

module_init(fira_region_init);
module_exit(fira_region_exit);

MODULE_DESCRIPTION("FiRa Region for IEEE 802.15.4 MCPS");
MODULE_AUTHOR("Nicolas Schodet <nicolas.schodet@qorvo.com>");
MODULE_VERSION("1.0");
MODULE_LICENSE("GPL v2");
