/*
 * Copyright (c) 2017 Intel Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(net_gptp, CONFIG_NET_GPTP_LOG_LEVEL);

#include <zephyr/net/net_pkt.h>
#include <zephyr/drivers/ptp_clock.h>
#include <zephyr/net/ethernet_mgmt.h>
#include <zephyr/random/random.h>

#include <zephyr/net/gptp.h>

#include "gptp_messages.h"
#include "gptp_mi.h"
#include "gptp_data_set.h"

#include "gptp_private.h"

#if CONFIG_NET_GPTP_NUM_PORTS > 32
/*
 * Boolean arrays sizes have been hardcoded.
 * It has been arbitrary chosen that a system can not
 * have more than 32 ports.
 */
#error Maximum number of ports exceeded. (Max is 32).
#endif

K_KERNEL_STACK_DEFINE(gptp_stack, CONFIG_NET_GPTP_STACK_SIZE);
K_FIFO_DEFINE(gptp_rx_queue);

static k_tid_t tid;
static struct k_thread gptp_thread_data;
struct gptp_domain gptp_domain;

int gptp_get_port_number(struct net_if *iface)
{
	int port = net_eth_get_ptp_port(iface) + 1;

	if (port >= GPTP_PORT_START && port < GPTP_PORT_END) {
		return port;
	}

	for (port = GPTP_PORT_START; port < GPTP_PORT_END; port++) {
		if (GPTP_PORT_IFACE(port) == iface) {
			return port;
		}
	}

	return -ENODEV;
}

bool gptp_is_slave_port(int port)
{
	return (GPTP_GLOBAL_DS()->selected_role[port] == GPTP_PORT_SLAVE);
}

/*
 * Use the given port to generate the clock identity
 * for the device.
 * The clock identity is unique for one time-aware system.
 */
static void gptp_compute_clock_identity(int port)
{
	struct net_if *iface = GPTP_PORT_IFACE(port);
	struct gptp_default_ds *default_ds;

	default_ds = GPTP_DEFAULT_DS();

	if (iface) {
		default_ds->clk_id[0] = net_if_get_link_addr(iface)->addr[0];
		default_ds->clk_id[1] = net_if_get_link_addr(iface)->addr[1];
		default_ds->clk_id[2] = net_if_get_link_addr(iface)->addr[2];
		default_ds->clk_id[3] = 0xFF;
		default_ds->clk_id[4] = 0xFE;
		default_ds->clk_id[5] = net_if_get_link_addr(iface)->addr[3];
		default_ds->clk_id[6] = net_if_get_link_addr(iface)->addr[4];
		default_ds->clk_id[7] = net_if_get_link_addr(iface)->addr[5];
	}
}

#define PRINT_INFO(msg, hdr, pkt)				\
	NET_DBG("Received %s seq %d pkt %p", (const char *)msg,	\
		ntohs(hdr->sequence_id), pkt)			\


static bool gptp_handle_critical_msg(struct net_if *iface, struct net_pkt *pkt)
{
	struct gptp_hdr *hdr = GPTP_HDR(pkt);
	bool handled = false;
	int port;

	switch (hdr->message_type) {
	case GPTP_PATH_DELAY_REQ_MESSAGE:
		if (GPTP_CHECK_LEN(pkt, GPTP_PDELAY_REQ_LEN)) {
			NET_WARN("Invalid length for %s packet "
				 "should have %zd bytes but has %zd bytes",
				 "PDELAY_REQ",
				 GPTP_PDELAY_REQ_LEN,
				 GPTP_PACKET_LEN(pkt));
			break;
		}

		PRINT_INFO("PDELAY_REQ", hdr, pkt);

		port = gptp_get_port_number(iface);
		if (port == -ENODEV) {
			NET_DBG("No port found for gPTP buffer");
			return handled;
		}

		if (GPTP_PORT_STATE(port)->pdelay_resp.state !=
						GPTP_PDELAY_RESP_NOT_ENABLED) {
			gptp_handle_pdelay_req(port, pkt);
		}

		handled = true;
		break;
	default:
		/* Not a critical message, this will be handled later. */
		break;
	}

	return handled;
}

static void gptp_handle_msg(struct net_pkt *pkt)
{
	struct gptp_hdr *hdr = GPTP_HDR(pkt);
	struct gptp_pdelay_req_state *pdelay_req_state;
	struct gptp_sync_rcv_state *sync_rcv_state;
	struct gptp_port_announce_receive_state *pa_rcv_state;
	struct gptp_port_bmca_data *bmca_data;
	int port;

	port = gptp_get_port_number(net_pkt_iface(pkt));
	if (port == -ENODEV) {
		NET_DBG("No port found for ptp buffer");
		return;
	}

	pdelay_req_state = &GPTP_PORT_STATE(port)->pdelay_req;
	sync_rcv_state = &GPTP_PORT_STATE(port)->sync_rcv;

	switch (hdr->message_type) {
	case GPTP_SYNC_MESSAGE:
		if (GPTP_CHECK_LEN(pkt, GPTP_SYNC_LEN)) {
			NET_WARN("Invalid length for %s packet "
				 "should have %zd bytes but has %zd bytes",
				 "SYNC",
				 GPTP_SYNC_LEN,
				 GPTP_PACKET_LEN(pkt));
			GPTP_STATS_INC(port, rx_ptp_packet_discard_count);
			break;
		}

		PRINT_INFO("SYNC", hdr, pkt);

		sync_rcv_state->rcvd_sync = true;

		/* If we already have one, drop the previous one. */
		if (sync_rcv_state->rcvd_sync_ptr) {
			net_pkt_unref(sync_rcv_state->rcvd_sync_ptr);
		}

		/* Keep the buffer alive until follow_up is received. */
		net_pkt_ref(pkt);
		sync_rcv_state->rcvd_sync_ptr = pkt;

		GPTP_STATS_INC(port, rx_sync_count);
		break;

	case GPTP_DELAY_REQ_MESSAGE:
		NET_DBG("Delay Request not handled.");
		break;

	case GPTP_PATH_DELAY_REQ_MESSAGE:
		/*
		 * Path Delay Responses to Path Delay Requests need
		 * very low latency. These need to handled in priority
		 * when received as they cannot afford to be delayed
		 * by context switches.
		 */
		NET_WARN("Path Delay Request received as normal messages!");
		GPTP_STATS_INC(port, rx_ptp_packet_discard_count);
		break;

	case GPTP_PATH_DELAY_RESP_MESSAGE:
		if (GPTP_CHECK_LEN(pkt, GPTP_PDELAY_RESP_LEN)) {
			NET_WARN("Invalid length for %s packet "
				 "should have %zd bytes but has %zd bytes",
				 "PDELAY_RESP",
				 GPTP_PDELAY_RESP_LEN,
				 GPTP_PACKET_LEN(pkt));
			GPTP_STATS_INC(port, rx_ptp_packet_discard_count);
			break;
		}

		PRINT_INFO("PDELAY_RESP", hdr, pkt);

		pdelay_req_state->rcvd_pdelay_resp++;

		/* If we already have one, drop the received one. */
		if (pdelay_req_state->rcvd_pdelay_resp_ptr) {
			break;
		}

		/* Keep the buffer alive until pdelay_rate_ratio is computed. */
		net_pkt_ref(pkt);
		pdelay_req_state->rcvd_pdelay_resp_ptr = pkt;
		break;

	case GPTP_FOLLOWUP_MESSAGE:
		if (GPTP_CHECK_LEN(pkt, GPTP_FOLLOW_UP_LEN)) {
			NET_WARN("Invalid length for %s packet "
				 "should have %zd bytes but has %zd bytes",
				 "FOLLOWUP",
				 GPTP_FOLLOW_UP_LEN,
				 GPTP_PACKET_LEN(pkt));
			GPTP_STATS_INC(port, rx_ptp_packet_discard_count);
			break;
		}

		PRINT_INFO("FOLLOWUP", hdr, pkt);

		sync_rcv_state->rcvd_follow_up = true;

		/* If we already have one, drop the previous one. */
		if (sync_rcv_state->rcvd_follow_up_ptr) {
			net_pkt_unref(sync_rcv_state->rcvd_follow_up_ptr);
		}

		/* Keep the pkt alive until info is extracted. */
		sync_rcv_state->rcvd_follow_up_ptr = net_pkt_ref(pkt);
		NET_DBG("Keeping %s seq %d pkt %p", "FOLLOWUP",
			ntohs(hdr->sequence_id), pkt);
		break;

	case GPTP_PATH_DELAY_FOLLOWUP_MESSAGE:
		if (GPTP_CHECK_LEN(pkt, GPTP_PDELAY_RESP_FUP_LEN)) {
			NET_WARN("Invalid length for %s packet "
				 "should have %zd bytes but has %zd bytes",
				 "PDELAY_FOLLOWUP",
				 GPTP_PDELAY_RESP_FUP_LEN,
				 GPTP_PACKET_LEN(pkt));
			GPTP_STATS_INC(port, rx_ptp_packet_discard_count);
			break;
		}

		PRINT_INFO("PDELAY_FOLLOWUP", hdr, pkt);

		pdelay_req_state->rcvd_pdelay_follow_up++;

		/* If we already have one, drop the received one. */
		if (pdelay_req_state->rcvd_pdelay_follow_up_ptr) {
			break;
		}

		/* Keep the buffer alive until pdelay_rate_ratio is computed. */
		net_pkt_ref(pkt);
		pdelay_req_state->rcvd_pdelay_follow_up_ptr = pkt;

		GPTP_STATS_INC(port, rx_pdelay_resp_fup_count);
		break;

	case GPTP_ANNOUNCE_MESSAGE:
		if (GPTP_ANNOUNCE_CHECK_LEN(pkt)) {
			NET_WARN("Invalid length for %s packet "
				 "should have %zd bytes but has %zd bytes",
				 "ANNOUNCE",
				 GPTP_ANNOUNCE_LEN(pkt),
				 GPTP_PACKET_LEN(pkt));
			GPTP_STATS_INC(port, rx_ptp_packet_discard_count);
			break;
		}

		PRINT_INFO("ANNOUNCE", hdr, pkt);

		pa_rcv_state = &GPTP_PORT_STATE(port)->pa_rcv;
		bmca_data = GPTP_PORT_BMCA_DATA(port);

		if (pa_rcv_state->rcvd_announce == false &&
				bmca_data->rcvd_announce_ptr == NULL) {
			pa_rcv_state->rcvd_announce = true;
			bmca_data->rcvd_announce_ptr = pkt;
			net_pkt_ref(pkt);
		}

		GPTP_STATS_INC(port, rx_announce_count);
		break;

	case GPTP_SIGNALING_MESSAGE:
		if (GPTP_CHECK_LEN(pkt, GPTP_SIGNALING_LEN)) {
			NET_WARN("Invalid length for %s packet "
				 "should have %zd bytes but has %zd bytes",
				 "SIGNALING",
				 GPTP_SIGNALING_LEN,
				 GPTP_PACKET_LEN(pkt));
			GPTP_STATS_INC(port, rx_ptp_packet_discard_count);
			break;
		}

		PRINT_INFO("SIGNALING", hdr, pkt);

		gptp_handle_signaling(port, pkt);
		break;

	case GPTP_MANAGEMENT_MESSAGE:
		PRINT_INFO("MANAGEMENT", hdr, pkt);
		GPTP_STATS_INC(port, rx_ptp_packet_discard_count);
		break;

	default:
		NET_DBG("Received unknown message %x", hdr->message_type);
		GPTP_STATS_INC(port, rx_ptp_packet_discard_count);
		break;
	}
}

enum net_verdict net_gptp_recv(struct net_if *iface, struct net_pkt *pkt)
{
	struct gptp_hdr *hdr = GPTP_HDR(pkt);

	if ((hdr->ptp_version != GPTP_VERSION) ||
			(hdr->transport_specific != GPTP_TRANSPORT_802_1_AS)) {
		/* The stack only supports PTP V2 and transportSpecific set
		 * to 1 with IEEE802.1AS-2011.
		 */
		return NET_DROP;
	}

	/* Handle critical messages. */
	if (!gptp_handle_critical_msg(iface, pkt)) {
		k_fifo_put(&gptp_rx_queue, pkt);

		/* Returning OK here makes sure the network statistics are
		 * properly updated.
		 */
		return NET_OK;
	}

	/* Message not propagated up in the stack. */
	return NET_DROP;
}

static void gptp_init_clock_ds(void)
{
	struct gptp_global_ds *global_ds;
	struct gptp_default_ds *default_ds;
	struct gptp_current_ds *current_ds;
	struct gptp_parent_ds *parent_ds;
	struct gptp_time_prop_ds *prop_ds;

	global_ds = GPTP_GLOBAL_DS();
	default_ds = GPTP_DEFAULT_DS();
	current_ds = GPTP_CURRENT_DS();
	parent_ds = GPTP_PARENT_DS();
	prop_ds = GPTP_PROPERTIES_DS();

	/* Initialize global data set. */
	(void)memset(global_ds, 0, sizeof(struct gptp_global_ds));

	/* Initialize default data set. */

	/* Compute the clock identity from the first port MAC address. */
	gptp_compute_clock_identity(GPTP_PORT_START);

	default_ds->gm_capable = IS_ENABLED(CONFIG_NET_GPTP_GM_CAPABLE);
	default_ds->clk_quality.clock_class = GPTP_CLASS_OTHER;
	default_ds->clk_quality.clock_accuracy =
		CONFIG_NET_GPTP_CLOCK_ACCURACY;
	default_ds->clk_quality.offset_scaled_log_var =
		GPTP_OFFSET_SCALED_LOG_VAR_UNKNOWN;

	if (default_ds->gm_capable) {
		/* The priority1 value cannot be 255 for GM capable
		 * system.
		 */
		if (CONFIG_NET_GPTP_BMCA_PRIORITY1 ==
		    GPTP_PRIORITY1_NON_GM_CAPABLE) {
			default_ds->priority1 = GPTP_PRIORITY1_GM_CAPABLE;
		} else {
			default_ds->priority1 = CONFIG_NET_GPTP_BMCA_PRIORITY1;
		}
	} else {
		default_ds->priority1 = GPTP_PRIORITY1_NON_GM_CAPABLE;
	}

	default_ds->priority2 = GPTP_PRIORITY2_DEFAULT;

	default_ds->cur_utc_offset = 37U; /* Current leap seconds TAI - UTC */
	default_ds->flags.all = 0U;
	default_ds->flags.octets[1] = GPTP_FLAG_TIME_TRACEABLE;
	default_ds->time_source = GPTP_TS_INTERNAL_OSCILLATOR;

	/* Initialize current data set. */
	(void)memset(current_ds, 0, sizeof(struct gptp_current_ds));

	/* Initialize parent data set. */

	/* parent clock id is initialized to default_ds clock id. */
	memcpy(parent_ds->port_id.clk_id, default_ds->clk_id,
	       GPTP_CLOCK_ID_LEN);
	memcpy(parent_ds->gm_id, default_ds->clk_id, GPTP_CLOCK_ID_LEN);
	parent_ds->port_id.port_number = 0U;

	/* TODO: Check correct value for below field. */
	parent_ds->cumulative_rate_ratio = 0;

	parent_ds->gm_clk_quality.clock_class =
		default_ds->clk_quality.clock_class;
	parent_ds->gm_clk_quality.clock_accuracy =
		default_ds->clk_quality.clock_accuracy;
	parent_ds->gm_clk_quality.offset_scaled_log_var =
		default_ds->clk_quality.offset_scaled_log_var;
	parent_ds->gm_priority1 = default_ds->priority1;
	parent_ds->gm_priority2 = default_ds->priority2;

	/* Initialize properties data set. */

	/* TODO: Get accurate values for below. From the GM. */
	prop_ds->cur_utc_offset = 37U; /* Current leap seconds TAI - UTC */
	prop_ds->cur_utc_offset_valid = false;
	prop_ds->leap59 = false;
	prop_ds->leap61 = false;
	prop_ds->time_traceable = false;
	prop_ds->freq_traceable = false;
	prop_ds->time_source = GPTP_TS_INTERNAL_OSCILLATOR;

	/* Set system values. */
	global_ds->sys_flags.all = default_ds->flags.all;
	global_ds->sys_current_utc_offset = default_ds->cur_utc_offset;
	global_ds->sys_time_source = default_ds->time_source;
	global_ds->clk_master_sync_itv =
		NSEC_PER_SEC * GPTP_POW2(CONFIG_NET_GPTP_INIT_LOG_SYNC_ITV);
}

static void gptp_init_port_ds(int port)
{
	struct gptp_default_ds *default_ds;
	struct gptp_port_ds *port_ds;

#if defined(CONFIG_NET_GPTP_STATISTICS)
	struct gptp_port_param_ds *port_param_ds;

	port_param_ds = GPTP_PORT_PARAM_DS(port);
#endif

	default_ds = GPTP_DEFAULT_DS();
	port_ds = GPTP_PORT_DS(port);

	/* Initialize port data set. */
	memcpy(port_ds->port_id.clk_id, default_ds->clk_id, GPTP_CLOCK_ID_LEN);
	port_ds->port_id.port_number = port;

	port_ds->ptt_port_enabled = true;
	port_ds->prev_ptt_port_enabled = true;

	port_ds->neighbor_prop_delay = 0;
	port_ds->neighbor_prop_delay_thresh = GPTP_NEIGHBOR_PROP_DELAY_THR;
	port_ds->delay_asymmetry = 0;

	port_ds->ini_log_announce_itv = CONFIG_NET_GPTP_INIT_LOG_ANNOUNCE_ITV;
	port_ds->cur_log_announce_itv = port_ds->ini_log_announce_itv;
	port_ds->announce_receipt_timeout =
		CONFIG_NET_GPTP_ANNOUNCE_RECEIPT_TIMEOUT;

	/* Subtract 1 to divide by 2 the sync interval. */
	port_ds->ini_log_half_sync_itv = CONFIG_NET_GPTP_INIT_LOG_SYNC_ITV - 1;
	port_ds->cur_log_half_sync_itv = port_ds->ini_log_half_sync_itv;
	port_ds->sync_receipt_timeout = CONFIG_NET_GPTP_SYNC_RECEIPT_TIMEOUT;
	port_ds->sync_receipt_timeout_time_itv = 10000000U; /* 10ms */

	port_ds->ini_log_pdelay_req_itv =
		CONFIG_NET_GPTP_INIT_LOG_PDELAY_REQ_ITV;
	port_ds->cur_log_pdelay_req_itv = port_ds->ini_log_pdelay_req_itv;
	port_ds->allowed_lost_responses = GPTP_ALLOWED_LOST_RESP;
	port_ds->version = GPTP_VERSION;

	gptp_set_time_itv(&port_ds->pdelay_req_itv, 1,
			  port_ds->cur_log_pdelay_req_itv);

	gptp_set_time_itv(&port_ds->half_sync_itv, 1,
			  port_ds->cur_log_half_sync_itv);

	port_ds->compute_neighbor_rate_ratio = true;
	port_ds->compute_neighbor_prop_delay = true;

	/* Random Sequence Numbers. */
	port_ds->sync_seq_id = (uint16_t)sys_rand32_get();
	port_ds->pdelay_req_seq_id = (uint16_t)sys_rand32_get();
	port_ds->announce_seq_id = (uint16_t)sys_rand32_get();
	port_ds->signaling_seq_id = (uint16_t)sys_rand32_get();

#if defined(CONFIG_NET_GPTP_STATISTICS)
	/* Initialize stats data set. */
	(void)memset(port_param_ds, 0, sizeof(struct gptp_port_param_ds));
#endif
}

static void gptp_init_state_machine(void)
{
	gptp_md_init_state_machine();
	gptp_mi_init_state_machine();
}

static void gptp_state_machine(void)
{
	int port;

	/* Manage port states. */
	for (port = GPTP_PORT_START; port < GPTP_PORT_END; port++) {
		struct gptp_port_ds *port_ds = GPTP_PORT_DS(port);

		/* If interface is down, don't move forward */
		if (net_if_flag_is_set(GPTP_PORT_IFACE(port), NET_IF_UP)) {
			switch (GPTP_GLOBAL_DS()->selected_role[port]) {
			case GPTP_PORT_DISABLED:
			case GPTP_PORT_MASTER:
			case GPTP_PORT_PASSIVE:
			case GPTP_PORT_SLAVE:
				gptp_md_state_machines(port);
				gptp_mi_port_sync_state_machines(port);
				gptp_mi_port_bmca_state_machines(port);
				break;
			default:
				NET_DBG("%s: Unknown port state", __func__);
				break;
			}
		} else {
			GPTP_GLOBAL_DS()->selected_role[port] = GPTP_PORT_DISABLED;
		}

		port_ds->prev_ptt_port_enabled = port_ds->ptt_port_enabled;
	}

	gptp_mi_state_machines();
}

static void gptp_thread(void *p1, void *p2, void *p3)
{
	ARG_UNUSED(p1);
	ARG_UNUSED(p2);
	ARG_UNUSED(p3);

	int port;

	NET_DBG("Starting PTP thread");

	gptp_init_clock_ds();

	for (port = GPTP_PORT_START; port < GPTP_PORT_END; port++) {
		gptp_init_port_ds(port);
		gptp_change_port_state(port, GPTP_PORT_DISABLED);
	}

	while (1) {
		struct net_pkt *pkt;

		pkt = k_fifo_get(&gptp_rx_queue,
				 K_MSEC(GPTP_THREAD_WAIT_TIMEOUT_MS));
		if (pkt) {
			gptp_handle_msg(pkt);
			net_pkt_unref(pkt);
		}

		gptp_state_machine();
	}
}


static void gptp_add_port(struct net_if *iface, void *user_data)
{
	int *num_ports = user_data;
	const struct device *clk;

	if (*num_ports >= CONFIG_NET_GPTP_NUM_PORTS) {
		return;
	}

	/* Check if interface has a PTP clock. */
	clk = net_eth_get_ptp_clock(iface);
	if (clk) {
		gptp_domain.iface[*num_ports] = iface;
		net_eth_set_ptp_port(iface, *num_ports);
		(*num_ports)++;
	}
}

void gptp_set_time_itv(struct gptp_uscaled_ns *interval,
		       uint16_t seconds,
		       int8_t log_msg_interval)
{
	int i;

	if (seconds == 0U) {
		interval->low = 0U;
		interval->high = 0U;
		return;
	} else if (log_msg_interval >= 96) {
		/* Overflow, set maximum. */
		interval->low = UINT64_MAX;
		interval->high = UINT32_MAX;

		return;
	} else if (log_msg_interval <= -64) {
		/* Underflow, set to 0. */
		interval->low = 0U;
		interval->high = 0U;
		return;
	}


	/* NSEC_PER_SEC is between 2^30 and 2^31, seconds is less thant 2^16,
	 * thus the computation will be less than 2^63.
	 */
	interval->low =	(seconds * (uint64_t)NSEC_PER_SEC) << 16;

	if (log_msg_interval <= 0) {
		interval->low >>= -log_msg_interval;
		interval->high = 0U;
	} else {
		/* Find highest bit set. */
		for (i = 63; i >= 0; i--) {
			if (interval->low >> i) {
				break;
			}
		}

		if ((i + log_msg_interval) >= 96 || log_msg_interval > 64) {
			/* Overflow, set maximum. */
			interval->low = UINT64_MAX;
			interval->high = UINT32_MAX;
		} else {
			interval->high =
				interval->low >> (64 - log_msg_interval);

			/* << operator is undefined if the shift value is equal
			 * to the number of bits in the left expression’s type
			 */
			if (log_msg_interval == 64) {
				interval->low = 0U;
			} else {
				interval->low <<= log_msg_interval;
			}
		}
	}
}

int32_t gptp_uscaled_ns_to_timer_ms(struct gptp_uscaled_ns *usns)
{
	uint64_t tmp;

	if (usns->high) {
		/* Do not calculate, it reaches max value. */
		return INT32_MAX;
	}

	tmp = (usns->low >> 16) / USEC_PER_SEC;
	if (tmp == 0U) {
		/* Timer must be started with a minimum value of 1. */
		return 1;
	}

	if (tmp > INT32_MAX) {
		return INT32_MAX;
	}

	return (tmp & INT32_MAX);

}

static int32_t timer_get_remaining_and_stop(struct k_timer *timer)
{
	unsigned int key;
	int32_t timer_value;

	key = irq_lock();
	timer_value = k_timer_remaining_get(timer);

	/* Stop timer as the period is about to be modified. */
	k_timer_stop(timer);
	irq_unlock(key);

	return timer_value;
}

static int32_t update_itv(struct gptp_uscaled_ns *itv,
			 int8_t *cur_log_itv,
			 int8_t *ini_log_itv,
			 int8_t new_log_itv,
			 int8_t correction_log_itv)
{
	switch (new_log_itv) {
	case GPTP_ITV_KEEP:
		break;
	case GPTP_ITV_SET_TO_INIT:
		*cur_log_itv = *ini_log_itv;
		gptp_set_time_itv(itv, 1, *ini_log_itv);
		break;
	case GPTP_ITV_STOP:
	default:
		*cur_log_itv = new_log_itv + correction_log_itv;
		gptp_set_time_itv(itv, 1, *cur_log_itv);
		break;
	}

	return gptp_uscaled_ns_to_timer_ms(itv);
}

void gptp_update_pdelay_req_interval(int port, int8_t log_val)
{
	int32_t remaining;
	int32_t new_itv, old_itv;
	struct gptp_pdelay_req_state *state_pdelay;
	struct gptp_port_ds *port_ds;

	port_ds = GPTP_PORT_DS(port);
	state_pdelay = &GPTP_PORT_STATE(port)->pdelay_req;
	remaining = timer_get_remaining_and_stop(&state_pdelay->pdelay_timer);

	old_itv = gptp_uscaled_ns_to_timer_ms(&port_ds->pdelay_req_itv);
	new_itv = update_itv(&port_ds->pdelay_req_itv,
			     &port_ds->cur_log_pdelay_req_itv,
			     &port_ds->ini_log_pdelay_req_itv,
			     log_val,
			     0);

	new_itv -= (old_itv-remaining);
	if (new_itv <= 0) {
		new_itv = 1;
	}

	k_timer_start(&state_pdelay->pdelay_timer, K_MSEC(new_itv), K_NO_WAIT);
}

void gptp_update_sync_interval(int port, int8_t log_val)
{
	struct gptp_pss_send_state *state_pss_send;
	struct gptp_port_ds *port_ds;
	int32_t new_itv, old_itv, period;
	int32_t remaining;
	uint32_t time_spent;

	port_ds = GPTP_PORT_DS(port);
	state_pss_send = &GPTP_PORT_STATE(port)->pss_send;
	remaining =
		timer_get_remaining_and_stop(
				&state_pss_send->half_sync_itv_timer);
	old_itv = gptp_uscaled_ns_to_timer_ms(&port_ds->half_sync_itv);
	new_itv = update_itv(&port_ds->half_sync_itv,
			     &port_ds->cur_log_half_sync_itv,
			     &port_ds->ini_log_half_sync_itv,
			     log_val,
			     -1);
	period = new_itv;

	/* Get the time spent from the start of the timer. */
	time_spent = old_itv;
	if (state_pss_send->half_sync_itv_timer_expired) {
		time_spent *= 2U;
	}
	time_spent -= remaining;

	/* Calculate remaining time and if half timer has expired. */
	if ((time_spent / 2U) > new_itv) {
		state_pss_send->sync_itv_timer_expired = true;
		state_pss_send->half_sync_itv_timer_expired = true;
		new_itv = 1;
	} else if (time_spent > new_itv) {
		state_pss_send->sync_itv_timer_expired = false;
		state_pss_send->half_sync_itv_timer_expired = true;
		new_itv -= (time_spent - new_itv);
	} else {
		state_pss_send->sync_itv_timer_expired = false;
		state_pss_send->half_sync_itv_timer_expired = false;
		new_itv -= time_spent;
	}

	if (new_itv <= 0) {
		new_itv = 1;
	}

	k_timer_start(&state_pss_send->half_sync_itv_timer, K_MSEC(new_itv),
		      K_MSEC(period));
}

void gptp_update_announce_interval(int port, int8_t log_val)
{
	int32_t remaining;
	int32_t new_itv, old_itv;
	struct gptp_port_announce_transmit_state *state_ann;
	struct gptp_port_bmca_data *bmca_data;
	struct gptp_port_ds *port_ds;

	port_ds = GPTP_PORT_DS(port);
	state_ann = &GPTP_PORT_STATE(port)->pa_transmit;
	bmca_data = GPTP_PORT_BMCA_DATA(port);
	remaining = timer_get_remaining_and_stop(
			&state_ann->ann_send_periodic_timer);

	old_itv = gptp_uscaled_ns_to_timer_ms(&bmca_data->announce_interval);
	new_itv = update_itv(&bmca_data->announce_interval,
			     &port_ds->cur_log_announce_itv,
			     &port_ds->ini_log_announce_itv,
			     log_val,
			     0);

	new_itv -= (old_itv-remaining);
	if (new_itv <= 0) {
		new_itv = 1;
	}

	k_timer_start(&state_ann->ann_send_periodic_timer, K_MSEC(new_itv),
		      K_NO_WAIT);
}

struct port_user_data {
	gptp_port_cb_t cb;
	void *user_data;
};

static void gptp_get_port(struct net_if *iface, void *user_data)
{
	struct port_user_data *ud = user_data;
	const struct device *clk;

	/* Check if interface has a PTP clock. */
	clk = net_eth_get_ptp_clock(iface);
	if (clk) {
		int port = gptp_get_port_number(iface);

		if (port < 0) {
			return;
		}

		ud->cb(port, iface, ud->user_data);
	}
}

void gptp_foreach_port(gptp_port_cb_t cb, void *user_data)
{
	struct port_user_data ud = {
		.cb = cb,
		.user_data = user_data
	};

	net_if_foreach(gptp_get_port, &ud);
}

struct gptp_domain *gptp_get_domain(void)
{
	return &gptp_domain;
}

int gptp_get_port_data(struct gptp_domain *domain,
		       int port,
		       struct gptp_port_ds **port_ds,
		       struct gptp_port_param_ds **port_param_ds,
		       struct gptp_port_states **port_state,
		       struct gptp_port_bmca_data **port_bmca_data,
		       struct net_if **iface)
{
	if (domain != &gptp_domain) {
		return -ENOENT;
	}

	if (port < GPTP_PORT_START || port >= GPTP_PORT_END) {
		return -EINVAL;
	}

	if (port_ds) {
		*port_ds = GPTP_PORT_DS(port);
	}

	if (port_param_ds) {
#if defined(CONFIG_NET_GPTP_STATISTICS)
		*port_param_ds = GPTP_PORT_PARAM_DS(port);
#else
		*port_param_ds = NULL;
#endif
	}

	if (port_state) {
		*port_state = GPTP_PORT_STATE(port);
	}

	if (port_bmca_data) {
		*port_bmca_data = GPTP_PORT_BMCA_DATA(port);
	}

	if (iface) {
		*iface = GPTP_PORT_IFACE(port);
	}

	return 0;
}

static void init_ports(void)
{
	net_if_foreach(gptp_add_port, &gptp_domain.default_ds.nb_ports);

	/* Only initialize the state machine once the ports are known. */
	gptp_init_state_machine();

	tid = k_thread_create(&gptp_thread_data, gptp_stack,
			      K_KERNEL_STACK_SIZEOF(gptp_stack),
			      gptp_thread,
			      NULL, NULL, NULL, K_PRIO_COOP(5), 0, K_NO_WAIT);
	k_thread_name_set(&gptp_thread_data, "gptp");
}

void net_gptp_init(void)
{
	gptp_domain.default_ds.nb_ports = 0U;

	init_ports();
}
