/*
 * 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_NATIVE_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 if (mgmt_request == NET_REQUEST_ETHERNET_SET_T1S_PARAM) {
		if (net_if_is_up(iface)) {
			return -EACCES;
		}

		memcpy(&config.t1s_param, &params->t1s_param,
		       sizeof(struct ethernet_t1s_param));
		type = ETHERNET_CONFIG_TYPE_T1S_PARAM;
	} else if (mgmt_request == NET_REQUEST_ETHERNET_SET_TXINJECTION_MODE) {
		if (!is_hw_caps_supported(dev, ETHERNET_TXINJECTION_MODE)) {
			return -ENOTSUP;
		}

		config.txinjection_mode = params->txinjection_mode;
		type = ETHERNET_CONFIG_TYPE_TXINJECTION_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);

NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_T1S_PARAM,
				  ethernet_set_config);

NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_SET_TXINJECTION_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 if (mgmt_request == NET_REQUEST_ETHERNET_GET_TXINJECTION_MODE) {
		if (!is_hw_caps_supported(dev, ETHERNET_TXINJECTION_MODE)) {
			return -ENOTSUP;
		}

		type = ETHERNET_CONFIG_TYPE_TXINJECTION_MODE;

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

		params->txinjection_mode = config.txinjection_mode;
	} 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);

NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_ETHERNET_GET_TXINJECTION_MODE,
				  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
}
