// SPDX-License-Identifier: GPL-2.0
/*
 * DPAA2 Ethernet Switch ethtool support
 *
 * Copyright 2014-2016 Freescale Semiconductor Inc.
 * Copyright 2017-2018 NXP
 *
 */

#include <linux/ethtool.h>

#include "dpaa2-switch.h"

static struct {
	enum dpsw_counter id;
	char name[ETH_GSTRING_LEN];
} dpaa2_switch_ethtool_counters[] =  {
	{DPSW_CNT_ING_FRAME,		"[hw] rx frames"},
	{DPSW_CNT_ING_BYTE,		"[hw] rx bytes"},
	{DPSW_CNT_ING_FLTR_FRAME,	"[hw] rx filtered frames"},
	{DPSW_CNT_ING_FRAME_DISCARD,	"[hw] rx discarded frames"},
	{DPSW_CNT_ING_BCAST_FRAME,	"[hw] rx bcast frames"},
	{DPSW_CNT_ING_BCAST_BYTES,	"[hw] rx bcast bytes"},
	{DPSW_CNT_ING_MCAST_FRAME,	"[hw] rx mcast frames"},
	{DPSW_CNT_ING_MCAST_BYTE,	"[hw] rx mcast bytes"},
	{DPSW_CNT_EGR_FRAME,		"[hw] tx frames"},
	{DPSW_CNT_EGR_BYTE,		"[hw] tx bytes"},
	{DPSW_CNT_EGR_FRAME_DISCARD,	"[hw] tx discarded frames"},
	{DPSW_CNT_ING_NO_BUFF_DISCARD,	"[hw] rx nobuffer discards"},
};

#define DPAA2_SWITCH_NUM_COUNTERS	ARRAY_SIZE(dpaa2_switch_ethtool_counters)

static void dpaa2_switch_get_drvinfo(struct net_device *netdev,
				     struct ethtool_drvinfo *drvinfo)
{
	struct ethsw_port_priv *port_priv = netdev_priv(netdev);
	u16 version_major, version_minor;
	int err;

	strscpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));

	err = dpsw_get_api_version(port_priv->ethsw_data->mc_io, 0,
				   &version_major,
				   &version_minor);
	if (err)
		strscpy(drvinfo->fw_version, "N/A",
			sizeof(drvinfo->fw_version));
	else
		snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
			 "%u.%u", version_major, version_minor);

	strscpy(drvinfo->bus_info, dev_name(netdev->dev.parent->parent),
		sizeof(drvinfo->bus_info));
}

static int
dpaa2_switch_get_link_ksettings(struct net_device *netdev,
				struct ethtool_link_ksettings *link_ksettings)
{
	struct ethsw_port_priv *port_priv = netdev_priv(netdev);
	struct dpsw_link_state state = {0};
	int err = 0;

	if (dpaa2_switch_port_is_type_phy(port_priv))
		return phylink_ethtool_ksettings_get(port_priv->mac->phylink,
						     link_ksettings);

	err = dpsw_if_get_link_state(port_priv->ethsw_data->mc_io, 0,
				     port_priv->ethsw_data->dpsw_handle,
				     port_priv->idx,
				     &state);
	if (err) {
		netdev_err(netdev, "ERROR %d getting link state\n", err);
		goto out;
	}

	/* At the moment, we have no way of interrogating the DPMAC
	 * from the DPSW side or there may not exist a DPMAC at all.
	 * Report only autoneg state, duplexity and speed.
	 */
	if (state.options & DPSW_LINK_OPT_AUTONEG)
		link_ksettings->base.autoneg = AUTONEG_ENABLE;
	if (!(state.options & DPSW_LINK_OPT_HALF_DUPLEX))
		link_ksettings->base.duplex = DUPLEX_FULL;
	link_ksettings->base.speed = state.rate;

out:
	return err;
}

static int
dpaa2_switch_set_link_ksettings(struct net_device *netdev,
				const struct ethtool_link_ksettings *link_ksettings)
{
	struct ethsw_port_priv *port_priv = netdev_priv(netdev);
	struct ethsw_core *ethsw = port_priv->ethsw_data;
	struct dpsw_link_cfg cfg = {0};
	bool if_running;
	int err = 0, ret;

	if (dpaa2_switch_port_is_type_phy(port_priv))
		return phylink_ethtool_ksettings_set(port_priv->mac->phylink,
						     link_ksettings);

	/* Interface needs to be down to change link settings */
	if_running = netif_running(netdev);
	if (if_running) {
		err = dpsw_if_disable(ethsw->mc_io, 0,
				      ethsw->dpsw_handle,
				      port_priv->idx);
		if (err) {
			netdev_err(netdev, "dpsw_if_disable err %d\n", err);
			return err;
		}
	}

	cfg.rate = link_ksettings->base.speed;
	if (link_ksettings->base.autoneg == AUTONEG_ENABLE)
		cfg.options |= DPSW_LINK_OPT_AUTONEG;
	else
		cfg.options &= ~DPSW_LINK_OPT_AUTONEG;
	if (link_ksettings->base.duplex  == DUPLEX_HALF)
		cfg.options |= DPSW_LINK_OPT_HALF_DUPLEX;
	else
		cfg.options &= ~DPSW_LINK_OPT_HALF_DUPLEX;

	err = dpsw_if_set_link_cfg(port_priv->ethsw_data->mc_io, 0,
				   port_priv->ethsw_data->dpsw_handle,
				   port_priv->idx,
				   &cfg);

	if (if_running) {
		ret = dpsw_if_enable(ethsw->mc_io, 0,
				     ethsw->dpsw_handle,
				     port_priv->idx);
		if (ret) {
			netdev_err(netdev, "dpsw_if_enable err %d\n", ret);
			return ret;
		}
	}
	return err;
}

static int
dpaa2_switch_ethtool_get_sset_count(struct net_device *netdev, int sset)
{
	struct ethsw_port_priv *port_priv = netdev_priv(netdev);
	int num_ss_stats = DPAA2_SWITCH_NUM_COUNTERS;

	switch (sset) {
	case ETH_SS_STATS:
		if (port_priv->mac)
			num_ss_stats += dpaa2_mac_get_sset_count();
		return num_ss_stats;
	default:
		return -EOPNOTSUPP;
	}
}

static void dpaa2_switch_ethtool_get_strings(struct net_device *netdev,
					     u32 stringset, u8 *data)
{
	struct ethsw_port_priv *port_priv = netdev_priv(netdev);
	u8 *p = data;
	int i;

	switch (stringset) {
	case ETH_SS_STATS:
		for (i = 0; i < DPAA2_SWITCH_NUM_COUNTERS; i++) {
			memcpy(p, dpaa2_switch_ethtool_counters[i].name,
			       ETH_GSTRING_LEN);
			p += ETH_GSTRING_LEN;
		}
		if (port_priv->mac)
			dpaa2_mac_get_strings(p);
		break;
	}
}

static void dpaa2_switch_ethtool_get_stats(struct net_device *netdev,
					   struct ethtool_stats *stats,
					   u64 *data)
{
	struct ethsw_port_priv *port_priv = netdev_priv(netdev);
	int i, err;

	for (i = 0; i < DPAA2_SWITCH_NUM_COUNTERS; i++) {
		err = dpsw_if_get_counter(port_priv->ethsw_data->mc_io, 0,
					  port_priv->ethsw_data->dpsw_handle,
					  port_priv->idx,
					  dpaa2_switch_ethtool_counters[i].id,
					  &data[i]);
		if (err)
			netdev_err(netdev, "dpsw_if_get_counter[%s] err %d\n",
				   dpaa2_switch_ethtool_counters[i].name, err);
	}

	if (port_priv->mac)
		dpaa2_mac_get_ethtool_stats(port_priv->mac, data + i);
}

const struct ethtool_ops dpaa2_switch_port_ethtool_ops = {
	.get_drvinfo		= dpaa2_switch_get_drvinfo,
	.get_link		= ethtool_op_get_link,
	.get_link_ksettings	= dpaa2_switch_get_link_ksettings,
	.set_link_ksettings	= dpaa2_switch_set_link_ksettings,
	.get_strings		= dpaa2_switch_ethtool_get_strings,
	.get_ethtool_stats	= dpaa2_switch_ethtool_get_stats,
	.get_sset_count		= dpaa2_switch_ethtool_get_sset_count,
};
