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

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(net_ethernet_mgmt, CONFIG_NET_L2_ETHERNET_LOG_LEVEL);

#include <errno.h>

#include <zephyr/net/net_core.h>
#include <zephyr/net/net_if.h>
#include <zephyr/net/ethernet_mgmt.h>

static inline bool is_hw_caps_supported(const struct device *dev,
					enum ethernet_hw_caps caps)
{
	const struct ethernet_api *api = dev->api;

	if (!api) {
		return false;
	}

	return !!(api->get_capabilities(dev) & caps);
}

static int ethernet_set_config(uint32_t mgmt_request,
			       struct net_if *iface,
			       void *data, size_t len)
{
	struct ethernet_req_params *params = (struct ethernet_req_params *)data;
	const struct device *dev = net_if_get_device(iface);
	const struct ethernet_api *api = dev->api;
	struct ethernet_config config = { 0 };
	enum ethernet_config_type type;

	if (!api) {
		return -ENOENT;
	}

	if (!api->set_config) {
		return -ENOTSUP;
	}

	if (!data || (len != sizeof(struct ethernet_req_params))) {
		return -EINVAL;
	}

	if (mgmt_request == NET_REQUEST_ETHERNET_SET_AUTO_NEGOTIATION) {
		if (!is_hw_caps_supported(dev,
					  ETHERNET_AUTO_NEGOTIATION_SET)) {
			return -ENOTSUP;
		}

		config.auto_negotiation = params->auto_negotiation;
		type = ETHERNET_CONFIG_TYPE_AUTO_NEG;
	} else if (mgmt_request == NET_REQUEST_ETHERNET_SET_LINK) {
		if (params->l.link_10bt) {
			if (!is_hw_caps_supported(dev,
						  ETHERNET_LINK_10BASE_T)) {
				return -ENOTSUP;
			}

			config.l.link_10bt = true;
		} else if (params->l.link_100bt) {
			if (!is_hw_caps_supported(dev,
						  ETHERNET_LINK_100BASE_T)) {
				return -ENOTSUP;
			}

			config.l.link_100bt = true;
		} else if (params->l.link_1000bt) {
			if (!is_hw_caps_supported(dev,
						  ETHERNET_LINK_1000BASE_T)) {
				return -ENOTSUP;
			}

			config.l.link_1000bt = true;
		} else {
			return -EINVAL;
		}

		type = ETHERNET_CONFIG_TYPE_LINK;
	} else if (mgmt_request == NET_REQUEST_ETHERNET_SET_DUPLEX) {
		if (!is_hw_caps_supported(dev, ETHERNET_DUPLEX_SET)) {
			return -ENOTSUP;
		}

		config.full_duplex = params->full_duplex;
		type = ETHERNET_CONFIG_TYPE_DUPLEX;
	} else if (mgmt_request == NET_REQUEST_ETHERNET_SET_MAC_ADDRESS) {
		if (net_if_is_up(iface)) {
			return -EACCES;
		}

		/* We need to remove the old IPv6 link layer address, that is
		 * generated from old MAC address, from network interface if
		 * needed.
		 */
		if (IS_ENABLED(CONFIG_NET_IPV6)) {
			struct in6_addr iid;

			net_ipv6_addr_create_iid(&iid,
						 net_if_get_link_addr(iface));

			/* No need to check the return value in this case. It
			 * is not an error if the address is not found atm.
			 */
			(void)net_if_ipv6_addr_rm(iface, &iid);
		}

		memcpy(&config.mac_address, &params->mac_address,
		       sizeof(struct net_eth_addr));
		type = ETHERNET_CONFIG_TYPE_MAC_ADDRESS;
	} else if (mgmt_request == NET_REQUEST_ETHERNET_SET_QAV_PARAM) {
		if (!is_hw_caps_supported(dev, ETHERNET_QAV)) {
			return -ENOTSUP;
		}

		/* Validate params which need global validating */
		switch (params->qav_param.type) {
		case ETHERNET_QAV_PARAM_TYPE_DELTA_BANDWIDTH:
			if (params->qav_param.delta_bandwidth > 100) {
				return -EINVAL;
			}
			break;
		case ETHERNET_QAV_PARAM_TYPE_OPER_IDLE_SLOPE:
		case ETHERNET_QAV_PARAM_TYPE_TRAFFIC_CLASS:
			/* Read-only parameters */
			return -EINVAL;
		default:
			/* No validation needed */
			break;
		}

		memcpy(&config.qav_param, &params->qav_param,
		       sizeof(struct ethernet_qav_param));
		type = ETHERNET_CONFIG_TYPE_QAV_PARAM;
	} else if (mgmt_request == NET_REQUEST_ETHERNET_SET_QBV_PARAM) {
		if (!is_hw_caps_supported(dev, ETHERNET_QBV)) {
			return -ENOTSUP;
		}

		/* Validate params which need global validating */
		if (params->qbv_param.state == ETHERNET_QBV_STATE_TYPE_OPER) {
			/* Read-only parameters */
			return -EINVAL;
		}

		if (params->qbv_param.type == ETHERNET_QBV_PARAM_TYPE_TIME &&
		    (params->qbv_param.cycle_time.nanosecond >= 1000000000 ||
		     params->qbv_param.base_time.fract_nsecond >= 1000000000)) {
			return -EINVAL;
		}

		memcpy(&config.qbv_param, &params->qbv_param,
		       sizeof(struct ethernet_qbv_param));
		type = ETHERNET_CONFIG_TYPE_QBV_PARAM;
	} else if (mgmt_request == NET_REQUEST_ETHERNET_SET_QBU_PARAM) {
		if (!is_hw_caps_supported(dev, ETHERNET_QBU)) {
			return -ENOTSUP;
		}

		if (params->qbu_param.type ==
		    ETHERNET_QBR_PARAM_TYPE_LINK_PARTNER_STATUS) {
			/* Read only parameter */
			return -EINVAL;
		}

		/* All other fields are rw */

		memcpy(&config.qbu_param, &params->qbu_param,
		       sizeof(struct ethernet_qbu_param));
		type = ETHERNET_CONFIG_TYPE_QBU_PARAM;
	} else if (mgmt_request == NET_REQUEST_ETHERNET_SET_TXTIME_PARAM) {
		if (!is_hw_caps_supported(dev, ETHERNET_TXTIME)) {
			return -ENOTSUP;
		}

		if (net_if_is_up(iface)) {
			return -EACCES;
		}

		memcpy(&config.txtime_param, &params->txtime_param,
		       sizeof(struct ethernet_txtime_param));
		type = ETHERNET_CONFIG_TYPE_TXTIME_PARAM;
	} else if (mgmt_request == NET_REQUEST_ETHERNET_SET_PROMISC_MODE) {
		if (!is_hw_caps_supported(dev, ETHERNET_PROMISC_MODE)) {
			return -ENOTSUP;
		}

		config.promisc_mode = params->promisc_mode;
		type = ETHERNET_CONFIG_TYPE_PROMISC_MODE;
	} else {
		return -EINVAL;
	}

	return api->set_config(net_if_get_device(iface), type, &config);
}

NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_AUTO_NEGOTIATION,
				  ethernet_set_config);

NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_LINK,
				  ethernet_set_config);

NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_DUPLEX,
				  ethernet_set_config);

NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_MAC_ADDRESS,
				  ethernet_set_config);

NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_QAV_PARAM,
				  ethernet_set_config);

NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_QBV_PARAM,
				  ethernet_set_config);

NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_QBU_PARAM,
				  ethernet_set_config);

NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_TXTIME_PARAM,
				  ethernet_set_config);

NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_PROMISC_MODE,
				  ethernet_set_config);

static int ethernet_get_config(uint32_t mgmt_request,
			       struct net_if *iface,
			       void *data, size_t len)
{
	struct ethernet_req_params *params = (struct ethernet_req_params *)data;
	const struct device *dev = net_if_get_device(iface);
	const struct ethernet_api *api = dev->api;
	struct ethernet_config config = { 0 };
	int ret = 0;
	enum ethernet_config_type type;

	if (!api) {
		return -ENOENT;
	}

	if (!api->get_config) {
		return -ENOTSUP;
	}

	if (!data || (len != sizeof(struct ethernet_req_params))) {
		return -EINVAL;
	}

	if (mgmt_request == NET_REQUEST_ETHERNET_GET_PRIORITY_QUEUES_NUM) {
		if (!is_hw_caps_supported(dev, ETHERNET_PRIORITY_QUEUES)) {
			return -ENOTSUP;
		}

		type = ETHERNET_CONFIG_TYPE_PRIORITY_QUEUES_NUM;

		ret = api->get_config(dev, type, &config);
		if (ret) {
			return ret;
		}

		params->priority_queues_num = config.priority_queues_num;
	} else if (mgmt_request == NET_REQUEST_ETHERNET_GET_QAV_PARAM) {
		if (!is_hw_caps_supported(dev, ETHERNET_QAV)) {
			return -ENOTSUP;
		}

		config.qav_param.queue_id = params->qav_param.queue_id;
		config.qav_param.type = params->qav_param.type;

		type = ETHERNET_CONFIG_TYPE_QAV_PARAM;

		ret = api->get_config(dev, type, &config);
		if (ret) {
			return ret;
		}

		switch (config.qav_param.type) {
		case ETHERNET_QAV_PARAM_TYPE_DELTA_BANDWIDTH:
			params->qav_param.delta_bandwidth =
				config.qav_param.delta_bandwidth;
			break;
		case ETHERNET_QAV_PARAM_TYPE_IDLE_SLOPE:
			params->qav_param.idle_slope =
				config.qav_param.idle_slope;
			break;
		case ETHERNET_QAV_PARAM_TYPE_OPER_IDLE_SLOPE:
			params->qav_param.oper_idle_slope =
				config.qav_param.oper_idle_slope;
			break;
		case ETHERNET_QAV_PARAM_TYPE_TRAFFIC_CLASS:
			params->qav_param.traffic_class =
				config.qav_param.traffic_class;
			break;
		case ETHERNET_QAV_PARAM_TYPE_STATUS:
			params->qav_param.enabled = config.qav_param.enabled;
			break;
		}

	} else if (mgmt_request == NET_REQUEST_ETHERNET_GET_PORTS_NUM) {
		type = ETHERNET_CONFIG_TYPE_PORTS_NUM;

		ret = api->get_config(dev, type, &config);
		if (ret) {
			return ret;
		}

		params->ports_num = config.ports_num;

	} else if (mgmt_request == NET_REQUEST_ETHERNET_GET_QBV_PARAM) {
		if (!is_hw_caps_supported(dev, ETHERNET_QBV)) {
			return -ENOTSUP;
		}

		config.qbv_param.port_id = params->qbv_param.port_id;
		config.qbv_param.type = params->qbv_param.type;
		config.qbv_param.state = params->qbv_param.state;

		if (config.qbv_param.type ==
		    ETHERNET_QBV_PARAM_TYPE_GATE_CONTROL_LIST) {
			config.qbv_param.gate_control.row =
				params->qbv_param.gate_control.row;
		}

		type = ETHERNET_CONFIG_TYPE_QBV_PARAM;

		ret = api->get_config(dev, type, &config);
		if (ret) {
			return ret;
		}

		switch (config.qbv_param.type) {
		case ETHERNET_QBV_PARAM_TYPE_STATUS:
			params->qbv_param.enabled = config.qbv_param.enabled;
			break;
		case ETHERNET_QBV_PARAM_TYPE_TIME:
			memcpy(&params->qbv_param.cycle_time,
			       &config.qbv_param.cycle_time,
			       sizeof(params->qbv_param.cycle_time));
			memcpy(&params->qbv_param.base_time,
			       &config.qbv_param.base_time,
			       sizeof(params->qbv_param.base_time));
			params->qbv_param.extension_time =
				config.qbv_param.extension_time;
			break;
		case ETHERNET_QBV_PARAM_TYPE_GATE_CONTROL_LIST_LEN:
			params->qbv_param.gate_control_list_len =
				config.qbv_param.gate_control_list_len;
			break;
		case ETHERNET_QBV_PARAM_TYPE_GATE_CONTROL_LIST:
			memcpy(&params->qbv_param.gate_control,
			       &config.qbv_param.gate_control,
			       sizeof(params->qbv_param.gate_control));
			break;
		}

	} else if (mgmt_request == NET_REQUEST_ETHERNET_GET_QBU_PARAM) {
		if (!is_hw_caps_supported(dev, ETHERNET_QBU)) {
			return -ENOTSUP;
		}

		config.qbu_param.port_id = params->qbu_param.port_id;
		config.qbu_param.type = params->qbu_param.type;

		type = ETHERNET_CONFIG_TYPE_QBU_PARAM;

		ret = api->get_config(dev, type, &config);
		if (ret) {
			return ret;
		}

		switch (config.qbu_param.type) {
		case ETHERNET_QBU_PARAM_TYPE_STATUS:
			params->qbu_param.enabled = config.qbu_param.enabled;
			break;
		case ETHERNET_QBU_PARAM_TYPE_RELEASE_ADVANCE:
			params->qbu_param.release_advance =
				config.qbu_param.release_advance;
			break;
		case ETHERNET_QBU_PARAM_TYPE_HOLD_ADVANCE:
			params->qbu_param.hold_advance =
				config.qbu_param.hold_advance;
			break;
		case ETHERNET_QBR_PARAM_TYPE_LINK_PARTNER_STATUS:
			params->qbu_param.link_partner_status =
				config.qbu_param.link_partner_status;
			break;
		case ETHERNET_QBR_PARAM_TYPE_ADDITIONAL_FRAGMENT_SIZE:
			params->qbu_param.additional_fragment_size =
				config.qbu_param.additional_fragment_size;
			break;
		case ETHERNET_QBU_PARAM_TYPE_PREEMPTION_STATUS_TABLE:
			memcpy(&params->qbu_param.frame_preempt_statuses,
			     &config.qbu_param.frame_preempt_statuses,
			     sizeof(params->qbu_param.frame_preempt_statuses));
			break;
		}

	} else if (mgmt_request == NET_REQUEST_ETHERNET_GET_TXTIME_PARAM) {
		if (!is_hw_caps_supported(dev, ETHERNET_TXTIME)) {
			return -ENOTSUP;
		}

		config.txtime_param.queue_id = params->txtime_param.queue_id;
		config.txtime_param.type = params->txtime_param.type;

		type = ETHERNET_CONFIG_TYPE_TXTIME_PARAM;

		ret = api->get_config(dev, type, &config);
		if (ret) {
			return ret;
		}

		switch (config.txtime_param.type) {
		case ETHERNET_TXTIME_PARAM_TYPE_ENABLE_QUEUES:
			params->txtime_param.enable_txtime =
				config.txtime_param.enable_txtime;
			break;
		}
	} else {
		return -EINVAL;
	}

	return ret;
}

NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_GET_PRIORITY_QUEUES_NUM,
				  ethernet_get_config);

NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_GET_QAV_PARAM,
				  ethernet_get_config);

NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_GET_PORTS_NUM,
				  ethernet_get_config);

NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_GET_QBV_PARAM,
				  ethernet_get_config);

NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_GET_QBU_PARAM,
				  ethernet_get_config);

NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_GET_TXTIME_PARAM,
				  ethernet_get_config);

void ethernet_mgmt_raise_carrier_on_event(struct net_if *iface)
{
	net_mgmt_event_notify(NET_EVENT_ETHERNET_CARRIER_ON, iface);
}

void ethernet_mgmt_raise_carrier_off_event(struct net_if *iface)
{
	net_mgmt_event_notify(NET_EVENT_ETHERNET_CARRIER_OFF, iface);
}

void ethernet_mgmt_raise_vlan_enabled_event(struct net_if *iface, uint16_t tag)
{
#if defined(CONFIG_NET_MGMT_EVENT_INFO)
	net_mgmt_event_notify_with_info(NET_EVENT_ETHERNET_VLAN_TAG_ENABLED,
					iface, &tag, sizeof(tag));
#else
	net_mgmt_event_notify(NET_EVENT_ETHERNET_VLAN_TAG_ENABLED,
			      iface);
#endif
}

void ethernet_mgmt_raise_vlan_disabled_event(struct net_if *iface, uint16_t tag)
{
#if defined(CONFIG_NET_MGMT_EVENT_INFO)
	net_mgmt_event_notify_with_info(NET_EVENT_ETHERNET_VLAN_TAG_DISABLED,
					iface, &tag, sizeof(tag));
#else
	net_mgmt_event_notify(NET_EVENT_ETHERNET_VLAN_TAG_DISABLED, iface);
#endif
}
