/** @file
 * @brief DSA related functions
 */

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

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(net_dsa, CONFIG_NET_DSA_LOG_LEVEL);

#include <errno.h>
#include <stdlib.h>

#include <zephyr/net/net_core.h>
#include <zephyr/net/ethernet.h>
#include <zephyr/net/net_mgmt.h>
#include <zephyr/net/dsa.h>

/*
 * Store, in the ethernet_context for master interface, the original
 * eth_tx() function, which will send packet with tag appended.
 */
int dsa_register_master_tx(struct net_if *iface, dsa_send_t fn)
{
	struct ethernet_context *ctx = net_if_l2_data(iface);

	ctx->dsa_send = fn;
	return 0;
}

#ifdef CONFIG_NET_L2_ETHERNET
bool dsa_is_port_master(struct net_if *iface)
{
	/* First check if iface points to ETH interface */
	if (net_if_l2(iface) == &NET_L2_GET_NAME(ETHERNET)) {
		/* Check its capabilities */
		if (net_eth_get_hw_capabilities(iface) &
		    ETHERNET_DSA_MASTER_PORT) {
			return true;
		}
	}

	return false;
}
#else
bool dsa_is_port_master(struct net_if *iface)
{
	return false;
}
#endif

/*
 * RECEIVE HANDLING CODE - ingress (ETH -> DSA slave ports)
 */

static int dsa_check_iface(struct net_if *iface)
{
	if (net_if_l2(iface) != &NET_L2_GET_NAME(ETHERNET)) {
		return -ENOENT;
	}

	if (!((net_eth_get_hw_capabilities(iface) & ETHERNET_DSA_MASTER_PORT) ||
	    (net_eth_get_hw_capabilities(iface) & ETHERNET_DSA_SLAVE_PORT))) {
		return -ESRCH;
	}

	return 0;
}


int dsa_register_recv_callback(struct net_if *iface, dsa_net_recv_cb_t cb)
{
	struct ethernet_context *ctx;
	int ret;

	ret = dsa_check_iface(iface);
	if (ret < 0) {
		return ret;
	}

	if (cb) {
		ctx = net_if_l2_data(iface);
		ctx->dsa_recv_cb = cb;
	}

	return 0;
}

struct net_if *dsa_net_recv(struct net_if *iface, struct net_pkt **pkt)
{
	const struct ethernet_context *c;
	const struct dsa_context *ctx;
	struct net_if *iface_sw;
	int ret;

	if (*pkt == NULL || iface == NULL) {
		return NULL;
	}

	c = net_if_l2_data(iface);
	ctx = c->dsa_ctx;

	if (ctx == NULL || ctx->dapi == NULL) {
		return iface;
	}

	if (ctx->dapi->dsa_get_iface == NULL) {
		NET_ERR("DSA: No callback to set LAN interfaces!");
		return iface;
	}

	iface_sw = ctx->dapi->dsa_get_iface(iface, *pkt);

	ret = dsa_check_iface(iface_sw);
	if (ret < 0) {
		return iface_sw;
	}

	/*
	 * Optional code to change the destination interface with some
	 * custom callback (to e.g. filter/switch packets based on MAC).
	 *
	 * The callback shall be only present (and used) for lan1..3, but
	 * not for the master interface, which shall support all other
	 * protocols - i.e. UDP. ICMP, TCP.
	 */
	c = net_if_l2_data(iface_sw);
	if (c->dsa_recv_cb) {
		if (c->dsa_recv_cb(iface_sw, *pkt)) {
			return iface_sw;
		}
	}

	return iface;
}

/*
 * TRANSMISSION HANDLING CODE egress (DSA slave ports -> ETH)
 */
int dsa_tx(const struct device *dev, struct net_pkt *pkt)
{
	struct net_if *iface_master, *iface;
	struct ethernet_context *ctx;
	struct dsa_context *context;

	iface = net_if_lookup_by_dev(dev);
	if (dsa_is_port_master(iface)) {
		/*
		 * The master interface's ethernet_context structure holds
		 * pointer to its original eth_tx().
		 * The wrapper (i.e. dsa_tx()) is needed to modify packet -
		 * it appends tag to it.
		 */
		ctx = net_if_l2_data(iface);
		context = ctx->dsa_ctx;
		return ctx->dsa_send(dev,
				     context->dapi->dsa_xmit_pkt(iface, pkt));
	}

	context = dev->data;
	iface_master = context->iface_master;

	if (iface_master == NULL) {
		NET_ERR("DSA: No master interface!");
		return -ENODEV;
	}

	/*
	 * Here packets are send via lan{123} interfaces in user program.
	 * Those structs' ethernet_api only have .send callback set to point
	 * to this wrapper function.
	 *
	 * Hence, it is necessary to get this callback from master's ethernet
	 * context structure..
	 */

	/* Adjust packet for DSA routing and send it via master interface */
	ctx = net_if_l2_data(iface_master);
	return ctx->dsa_send(net_if_get_device(iface_master),
			     context->dapi->dsa_xmit_pkt(iface, pkt));
}

struct net_if *dsa_get_slave_port(struct net_if *iface, int slave_num)
{
	struct ethernet_context *eth_ctx;
	struct dsa_context *dsa_ctx;

	eth_ctx = net_if_l2_data(iface);
	if (eth_ctx == NULL) {
		LOG_ERR("Iface %p context not available!", iface);
		return NULL;
	}

	dsa_ctx = eth_ctx->dsa_ctx;

	if (slave_num < 0 || slave_num >= dsa_ctx->num_slave_ports) {
		return NULL;
	}

	return dsa_ctx->iface_slave[slave_num];
}

int dsa_switch_read(struct net_if *iface, uint16_t reg_addr, uint8_t *value)
{
	const struct device *dev = net_if_get_device(iface);
	struct dsa_context *context = dev->data;
	const struct dsa_api *api =
		(const struct dsa_api *)context->dapi;

	return api->switch_read(dev, reg_addr, value);
}

int dsa_switch_write(struct net_if *iface, uint16_t reg_addr, uint8_t value)
{
	const struct device *dev = net_if_get_device(iface);
	struct dsa_context *context = dev->data;
	const struct dsa_api *api =
		(const struct dsa_api *)context->dapi;

	return api->switch_write(dev, reg_addr, value);
}

/**
 * @brief      Write static MAC table entry
 *
 * @param      iface          DSA interface
 * @param[in]  mac            MAC address
 * @param[in]  fw_port        The firmware port
 * @param[in]  tbl_entry_idx  Table entry index
 * @param[in]  flags          Flags
 *
 * @return     0 if successful, negative if error
 */
int dsa_switch_set_mac_table_entry(struct net_if *iface,
					const uint8_t *mac,
					uint8_t fw_port,
					uint16_t tbl_entry_idx,
					uint16_t flags)
{
	const struct device *dev = net_if_get_device(iface);
	struct dsa_context *context = dev->data;
	const struct dsa_api *api =
		(const struct dsa_api *)context->dapi;

	return api->switch_set_mac_table_entry(dev, mac, fw_port,
							tbl_entry_idx, flags);
}

/**
 * @brief      Read static MAC table entry
 *
 * @param      iface          DSA interface
 * @param      buf            Buffer to receive MAC address
 * @param[in]  tbl_entry_idx  Table entry index
 *
 * @return     0 if successful, negative if error
 */
int dsa_switch_get_mac_table_entry(struct net_if *iface,
					uint8_t *buf,
					uint16_t tbl_entry_idx)
{
	const struct device *dev = net_if_get_device(iface);
	struct dsa_context *context = dev->data;
	const struct dsa_api *api =
		(const struct dsa_api *)context->dapi;

	return api->switch_get_mac_table_entry(dev, buf, tbl_entry_idx);
}
