// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2015 - 2023 Beijing WangXun Technology Co., Ltd. */

#include <linux/pci.h>
#include <linux/phylink.h>
#include <linux/netdevice.h>

#include "../libwx/wx_ethtool.h"
#include "../libwx/wx_type.h"
#include "../libwx/wx_lib.h"
#include "txgbe_type.h"
#include "txgbe_ethtool.h"

static int txgbe_set_ringparam(struct net_device *netdev,
			       struct ethtool_ringparam *ring,
			       struct kernel_ethtool_ringparam *kernel_ring,
			       struct netlink_ext_ack *extack)
{
	struct wx *wx = netdev_priv(netdev);
	u32 new_rx_count, new_tx_count;
	struct wx_ring *temp_ring;
	int i;

	new_tx_count = clamp_t(u32, ring->tx_pending, WX_MIN_TXD, WX_MAX_TXD);
	new_tx_count = ALIGN(new_tx_count, WX_REQ_TX_DESCRIPTOR_MULTIPLE);

	new_rx_count = clamp_t(u32, ring->rx_pending, WX_MIN_RXD, WX_MAX_RXD);
	new_rx_count = ALIGN(new_rx_count, WX_REQ_RX_DESCRIPTOR_MULTIPLE);

	if (new_tx_count == wx->tx_ring_count &&
	    new_rx_count == wx->rx_ring_count)
		return 0;

	if (!netif_running(wx->netdev)) {
		for (i = 0; i < wx->num_tx_queues; i++)
			wx->tx_ring[i]->count = new_tx_count;
		for (i = 0; i < wx->num_rx_queues; i++)
			wx->rx_ring[i]->count = new_rx_count;
		wx->tx_ring_count = new_tx_count;
		wx->rx_ring_count = new_rx_count;

		return 0;
	}

	/* allocate temporary buffer to store rings in */
	i = max_t(int, wx->num_tx_queues, wx->num_rx_queues);
	temp_ring = kvmalloc_array(i, sizeof(struct wx_ring), GFP_KERNEL);
	if (!temp_ring)
		return -ENOMEM;

	txgbe_down(wx);

	wx_set_ring(wx, new_tx_count, new_rx_count, temp_ring);
	kvfree(temp_ring);

	txgbe_up(wx);

	return 0;
}

static int txgbe_set_channels(struct net_device *dev,
			      struct ethtool_channels *ch)
{
	int err;

	err = wx_set_channels(dev, ch);
	if (err < 0)
		return err;

	/* use setup TC to update any traffic class queue mapping */
	return txgbe_setup_tc(dev, netdev_get_num_tc(dev));
}

static const struct ethtool_ops txgbe_ethtool_ops = {
	.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
				     ETHTOOL_COALESCE_TX_MAX_FRAMES_IRQ,
	.get_drvinfo		= wx_get_drvinfo,
	.nway_reset		= wx_nway_reset,
	.get_link		= ethtool_op_get_link,
	.get_link_ksettings	= wx_get_link_ksettings,
	.set_link_ksettings	= wx_set_link_ksettings,
	.get_sset_count		= wx_get_sset_count,
	.get_strings		= wx_get_strings,
	.get_ethtool_stats	= wx_get_ethtool_stats,
	.get_eth_mac_stats	= wx_get_mac_stats,
	.get_pause_stats	= wx_get_pause_stats,
	.get_pauseparam		= wx_get_pauseparam,
	.set_pauseparam		= wx_set_pauseparam,
	.get_ringparam		= wx_get_ringparam,
	.set_ringparam		= txgbe_set_ringparam,
	.get_coalesce		= wx_get_coalesce,
	.set_coalesce		= wx_set_coalesce,
	.get_channels		= wx_get_channels,
	.set_channels		= txgbe_set_channels,
	.get_msglevel		= wx_get_msglevel,
	.set_msglevel		= wx_set_msglevel,
};

void txgbe_set_ethtool_ops(struct net_device *netdev)
{
	netdev->ethtool_ops = &txgbe_ethtool_ops;
}
