/*
 * Copyright(c) 2017 Intel Corporation.
 *
 * This file is provided under a dual BSD/GPLv2 license.  When using or
 * redistributing this file, you may do so under either license.
 *
 * GPL LICENSE SUMMARY
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * 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.
 *
 * BSD LICENSE
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  - Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  - Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  - Neither the name of Intel Corporation nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

/*
 * This file contains OPA VNIC ethtool functions
 */

#include <linux/ethtool.h>

#include "opa_vnic_internal.h"

enum {NETDEV_STATS, VNIC_STATS};

struct vnic_stats {
	char stat_string[ETH_GSTRING_LEN];
	struct {
		int sizeof_stat;
		int stat_offset;
	};
};

#define VNIC_STAT(m)            { FIELD_SIZEOF(struct opa_vnic_stats, m),   \
				  offsetof(struct opa_vnic_stats, m) }

static struct vnic_stats vnic_gstrings_stats[] = {
	/* NETDEV stats */
	{"rx_packets", VNIC_STAT(netstats.rx_packets)},
	{"tx_packets", VNIC_STAT(netstats.tx_packets)},
	{"rx_bytes", VNIC_STAT(netstats.rx_bytes)},
	{"tx_bytes", VNIC_STAT(netstats.tx_bytes)},
	{"rx_errors", VNIC_STAT(netstats.rx_errors)},
	{"tx_errors", VNIC_STAT(netstats.tx_errors)},
	{"rx_dropped", VNIC_STAT(netstats.rx_dropped)},
	{"tx_dropped", VNIC_STAT(netstats.tx_dropped)},

	/* SUMMARY counters */
	{"tx_unicast", VNIC_STAT(tx_grp.unicast)},
	{"tx_mcastbcast", VNIC_STAT(tx_grp.mcastbcast)},
	{"tx_untagged", VNIC_STAT(tx_grp.untagged)},
	{"tx_vlan", VNIC_STAT(tx_grp.vlan)},

	{"tx_64_size", VNIC_STAT(tx_grp.s_64)},
	{"tx_65_127", VNIC_STAT(tx_grp.s_65_127)},
	{"tx_128_255", VNIC_STAT(tx_grp.s_128_255)},
	{"tx_256_511", VNIC_STAT(tx_grp.s_256_511)},
	{"tx_512_1023", VNIC_STAT(tx_grp.s_512_1023)},
	{"tx_1024_1518", VNIC_STAT(tx_grp.s_1024_1518)},
	{"tx_1519_max", VNIC_STAT(tx_grp.s_1519_max)},

	{"rx_unicast", VNIC_STAT(rx_grp.unicast)},
	{"rx_mcastbcast", VNIC_STAT(rx_grp.mcastbcast)},
	{"rx_untagged", VNIC_STAT(rx_grp.untagged)},
	{"rx_vlan", VNIC_STAT(rx_grp.vlan)},

	{"rx_64_size", VNIC_STAT(rx_grp.s_64)},
	{"rx_65_127", VNIC_STAT(rx_grp.s_65_127)},
	{"rx_128_255", VNIC_STAT(rx_grp.s_128_255)},
	{"rx_256_511", VNIC_STAT(rx_grp.s_256_511)},
	{"rx_512_1023", VNIC_STAT(rx_grp.s_512_1023)},
	{"rx_1024_1518", VNIC_STAT(rx_grp.s_1024_1518)},
	{"rx_1519_max", VNIC_STAT(rx_grp.s_1519_max)},

	/* ERROR counters */
	{"rx_fifo_errors", VNIC_STAT(netstats.rx_fifo_errors)},
	{"rx_length_errors", VNIC_STAT(netstats.rx_length_errors)},

	{"tx_fifo_errors", VNIC_STAT(netstats.tx_fifo_errors)},
	{"tx_carrier_errors", VNIC_STAT(netstats.tx_carrier_errors)},

	{"tx_dlid_zero", VNIC_STAT(tx_dlid_zero)},
	{"tx_drop_state", VNIC_STAT(tx_drop_state)},
	{"rx_drop_state", VNIC_STAT(rx_drop_state)},
	{"rx_oversize", VNIC_STAT(rx_oversize)},
	{"rx_runt", VNIC_STAT(rx_runt)},
};

#define VNIC_STATS_LEN  ARRAY_SIZE(vnic_gstrings_stats)

/* vnic_get_drvinfo - get driver info */
static void vnic_get_drvinfo(struct net_device *netdev,
			     struct ethtool_drvinfo *drvinfo)
{
	strlcpy(drvinfo->driver, opa_vnic_driver_name, sizeof(drvinfo->driver));
	strlcpy(drvinfo->version, opa_vnic_driver_version,
		sizeof(drvinfo->version));
	strlcpy(drvinfo->bus_info, dev_name(netdev->dev.parent),
		sizeof(drvinfo->bus_info));
}

/* vnic_get_sset_count - get string set count */
static int vnic_get_sset_count(struct net_device *netdev, int sset)
{
	return (sset == ETH_SS_STATS) ? VNIC_STATS_LEN : -EOPNOTSUPP;
}

/* vnic_get_ethtool_stats - get statistics */
static void vnic_get_ethtool_stats(struct net_device *netdev,
				   struct ethtool_stats *stats, u64 *data)
{
	struct opa_vnic_adapter *adapter = opa_vnic_priv(netdev);
	struct opa_vnic_stats vstats;
	int i;

	memset(&vstats, 0, sizeof(vstats));
	mutex_lock(&adapter->stats_lock);
	adapter->rn_ops->ndo_get_stats64(netdev, &vstats.netstats);
	for (i = 0; i < VNIC_STATS_LEN; i++) {
		char *p = (char *)&vstats + vnic_gstrings_stats[i].stat_offset;

		data[i] = (vnic_gstrings_stats[i].sizeof_stat ==
			   sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
	}
	mutex_unlock(&adapter->stats_lock);
}

/* vnic_get_strings - get strings */
static void vnic_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
{
	int i;

	if (stringset != ETH_SS_STATS)
		return;

	for (i = 0; i < VNIC_STATS_LEN; i++)
		memcpy(data + i * ETH_GSTRING_LEN,
		       vnic_gstrings_stats[i].stat_string,
		       ETH_GSTRING_LEN);
}

/* ethtool ops */
static const struct ethtool_ops opa_vnic_ethtool_ops = {
	.get_drvinfo = vnic_get_drvinfo,
	.get_link = ethtool_op_get_link,
	.get_strings = vnic_get_strings,
	.get_sset_count = vnic_get_sset_count,
	.get_ethtool_stats = vnic_get_ethtool_stats,
};

/* opa_vnic_set_ethtool_ops - set ethtool ops */
void opa_vnic_set_ethtool_ops(struct net_device *netdev)
{
	netdev->ethtool_ops = &opa_vnic_ethtool_ops;
}
