/*   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; version 2 of the License
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   Copyright (C) 2009-2016 John Crispin <blogic@openwrt.org>
 *   Copyright (C) 2009-2016 Felix Fietkau <nbd@openwrt.org>
 *   Copyright (C) 2013-2016 Michael Lee <igvtee@gmail.com>
 */

#include "mtk_eth_soc.h"
#include "ethtool.h"

struct mtk_stat {
	char name[ETH_GSTRING_LEN];
	unsigned int idx;
};

#define MTK_HW_STAT(stat) { \
	.name = #stat, \
	.idx = offsetof(struct mtk_hw_stats, stat) / sizeof(u64) \
}

static const struct mtk_stat mtk_ethtool_hw_stats[] = {
	MTK_HW_STAT(tx_bytes),
	MTK_HW_STAT(tx_packets),
	MTK_HW_STAT(tx_skip),
	MTK_HW_STAT(tx_collisions),
	MTK_HW_STAT(rx_bytes),
	MTK_HW_STAT(rx_packets),
	MTK_HW_STAT(rx_overflow),
	MTK_HW_STAT(rx_fcs_errors),
	MTK_HW_STAT(rx_short_errors),
	MTK_HW_STAT(rx_long_errors),
	MTK_HW_STAT(rx_checksum_errors),
	MTK_HW_STAT(rx_flow_control_packets),
};

#define MTK_HW_STATS_LEN	ARRAY_SIZE(mtk_ethtool_hw_stats)

static int mtk_get_link_ksettings(struct net_device *dev,
				  struct ethtool_link_ksettings *cmd)
{
	struct mtk_mac *mac = netdev_priv(dev);
	int err;

	if (!mac->phy_dev)
		return -ENODEV;

	if (mac->phy_flags == MTK_PHY_FLAG_ATTACH) {
		err = phy_read_status(mac->phy_dev);
		if (err)
			return -ENODEV;
	}

	phy_ethtool_ksettings_get(mac->phy_dev, cmd);
	return 0;
}

static int mtk_set_link_ksettings(struct net_device *dev,
				  const struct ethtool_link_ksettings *cmd)
{
	struct mtk_mac *mac = netdev_priv(dev);

	if (!mac->phy_dev)
		return -ENODEV;

	if (cmd->base.phy_address != mac->phy_dev->mdio.addr) {
		if (mac->hw->phy->phy_node[cmd->base.phy_address]) {
			mac->phy_dev = mac->hw->phy->phy[cmd->base.phy_address];
			mac->phy_flags = MTK_PHY_FLAG_PORT;
		} else if (mac->hw->mii_bus) {
			mac->phy_dev = mdiobus_get_phy(mac->hw->mii_bus,
						       cmd->base.phy_address);
			if (!mac->phy_dev)
				return -ENODEV;
			mac->phy_flags = MTK_PHY_FLAG_ATTACH;
		} else {
			return -ENODEV;
		}
	}

	return phy_ethtool_ksettings_set(mac->phy_dev, cmd);
}

static void mtk_get_drvinfo(struct net_device *dev,
			    struct ethtool_drvinfo *info)
{
	struct mtk_mac *mac = netdev_priv(dev);
	struct mtk_soc_data *soc = mac->hw->soc;

	strlcpy(info->driver, mac->hw->dev->driver->name, sizeof(info->driver));
	strlcpy(info->bus_info, dev_name(mac->hw->dev), sizeof(info->bus_info));

	if (soc->reg_table[MTK_REG_MTK_COUNTER_BASE])
		info->n_stats = MTK_HW_STATS_LEN;
}

static u32 mtk_get_msglevel(struct net_device *dev)
{
	struct mtk_mac *mac = netdev_priv(dev);

	return mac->hw->msg_enable;
}

static void mtk_set_msglevel(struct net_device *dev, u32 value)
{
	struct mtk_mac *mac = netdev_priv(dev);

	mac->hw->msg_enable = value;
}

static int mtk_nway_reset(struct net_device *dev)
{
	struct mtk_mac *mac = netdev_priv(dev);

	if (!mac->phy_dev)
		return -EOPNOTSUPP;

	return genphy_restart_aneg(mac->phy_dev);
}

static u32 mtk_get_link(struct net_device *dev)
{
	struct mtk_mac *mac = netdev_priv(dev);
	int err;

	if (!mac->phy_dev)
		goto out_get_link;

	if (mac->phy_flags == MTK_PHY_FLAG_ATTACH) {
		err = genphy_update_link(mac->phy_dev);
		if (err)
			goto out_get_link;
	}

	return mac->phy_dev->link;

out_get_link:
	return ethtool_op_get_link(dev);
}

static int mtk_set_ringparam(struct net_device *dev,
			     struct ethtool_ringparam *ring)
{
	struct mtk_mac *mac = netdev_priv(dev);

	if ((ring->tx_pending < 2) ||
	    (ring->rx_pending < 2) ||
	    (ring->rx_pending > mac->hw->soc->dma_ring_size) ||
	    (ring->tx_pending > mac->hw->soc->dma_ring_size))
		return -EINVAL;

	dev->netdev_ops->ndo_stop(dev);

	mac->hw->tx_ring.tx_ring_size = BIT(fls(ring->tx_pending) - 1);
	mac->hw->rx_ring[0].rx_ring_size = BIT(fls(ring->rx_pending) - 1);

	return dev->netdev_ops->ndo_open(dev);
}

static void mtk_get_ringparam(struct net_device *dev,
			      struct ethtool_ringparam *ring)
{
	struct mtk_mac *mac = netdev_priv(dev);

	ring->rx_max_pending = mac->hw->soc->dma_ring_size;
	ring->tx_max_pending = mac->hw->soc->dma_ring_size;
	ring->rx_pending = mac->hw->rx_ring[0].rx_ring_size;
	ring->tx_pending = mac->hw->tx_ring.tx_ring_size;
}

static void mtk_get_strings(struct net_device *dev, u32 stringset, u8 *data)
{
	int i;

	switch (stringset) {
	case ETH_SS_STATS:
		for (i = 0; i < MTK_HW_STATS_LEN; i++) {
			memcpy(data, mtk_ethtool_hw_stats[i].name,
			       ETH_GSTRING_LEN);
			data += ETH_GSTRING_LEN;
		}
		break;
	}
}

static int mtk_get_sset_count(struct net_device *dev, int sset)
{
	switch (sset) {
	case ETH_SS_STATS:
		return MTK_HW_STATS_LEN;
	default:
		return -EOPNOTSUPP;
	}
}

static void mtk_get_ethtool_stats(struct net_device *dev,
				  struct ethtool_stats *stats, u64 *data)
{
	struct mtk_mac *mac = netdev_priv(dev);
	struct mtk_hw_stats *hwstats = mac->hw_stats;
	unsigned int start;
	int i;

	if (netif_running(dev) && netif_device_present(dev)) {
		if (spin_trylock(&hwstats->stats_lock)) {
			mtk_stats_update_mac(mac);
			spin_unlock(&hwstats->stats_lock);
		}
	}

	do {
		start = u64_stats_fetch_begin_irq(&hwstats->syncp);
		for (i = 0; i < MTK_HW_STATS_LEN; i++)
			data[i] = ((u64 *)hwstats)[mtk_ethtool_hw_stats[i].idx];

	} while (u64_stats_fetch_retry_irq(&hwstats->syncp, start));
}

static struct ethtool_ops mtk_ethtool_ops = {
	.get_link_ksettings     = mtk_get_link_ksettings,
	.set_link_ksettings     = mtk_set_link_ksettings,
	.get_drvinfo		= mtk_get_drvinfo,
	.get_msglevel		= mtk_get_msglevel,
	.set_msglevel		= mtk_set_msglevel,
	.nway_reset		= mtk_nway_reset,
	.get_link		= mtk_get_link,
	.set_ringparam		= mtk_set_ringparam,
	.get_ringparam		= mtk_get_ringparam,
};

void mtk_set_ethtool_ops(struct net_device *netdev)
{
	struct mtk_mac *mac = netdev_priv(netdev);
	struct mtk_soc_data *soc = mac->hw->soc;

	if (soc->reg_table[MTK_REG_MTK_COUNTER_BASE]) {
		mtk_ethtool_ops.get_strings = mtk_get_strings;
		mtk_ethtool_ops.get_sset_count = mtk_get_sset_count;
		mtk_ethtool_ops.get_ethtool_stats = mtk_get_ethtool_stats;
	}

	netdev->ethtool_ops = &mtk_ethtool_ops;
}
