/*
 * 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; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * Copyright (C) Google, 2013
 */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/capability.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/netdevice.h>

#include "gbe/mvNeta.h"
#include "mv_netdev.h"

struct goog_net_attribute {
	struct device_attribute dev_attr;
	uint64_t val;
	uint32_t mib;
	uint32_t port;
};

#define GOOG_ATTR(_name, _portname, _show, _mib, _port)                 \
		struct goog_net_attribute goog_attr_##_name##_##_portname = {      \
			.dev_attr = __ATTR(_name, S_IRUSR, _show, NULL), \
			.mib= _mib,                             \
			.port = _port,                                   \
		}

static ssize_t goog_get_stat(struct device *dev,
							 struct device_attribute *attr, char *buf)
{
	MV_U32 reg_low, reg_high = 0;
	uint64_t reg_val;
	struct goog_net_attribute *goog_attr = container_of(attr, struct goog_net_attribute, dev_attr);
        // These mib registers are clear on read.
	reg_low = mvNetaMibCounterRead(goog_attr->port, 0, goog_attr->mib, &reg_high);
	reg_val = ((uint64_t)reg_high) << 32 | (uint64_t)reg_low;
	goog_attr->val += reg_val;
	return sprintf(buf, "%llu\n", goog_attr->val);
}

// Stats for the UNI port.
static GOOG_ATTR(rx_good_packets, uni, goog_get_stat, ETH_MIB_GOOD_FRAMES_RECEIVED, 0);
static GOOG_ATTR(rx_bad_packets, uni, goog_get_stat, ETH_MIB_BAD_FRAMES_RECEIVED, 0);
static GOOG_ATTR(rx_broadcast_packets, uni, goog_get_stat, ETH_MIB_BROADCAST_FRAMES_RECEIVED, 0);
static GOOG_ATTR(rx_multicast_packets, uni, goog_get_stat, ETH_MIB_MULTICAST_FRAMES_RECEIVED, 0);
static GOOG_ATTR(tx_good_packets, uni, goog_get_stat, ETH_MIB_GOOD_FRAMES_SENT, 0);
static GOOG_ATTR(tx_broadcast_packets, uni, goog_get_stat, ETH_MIB_BROADCAST_FRAMES_SENT, 0);
static GOOG_ATTR(tx_multicast_packets, uni, goog_get_stat, ETH_MIB_MULTICAST_FRAMES_SENT, 0);

static struct attribute *goog_uni_attrs[] = {
	&goog_attr_rx_good_packets_uni.dev_attr.attr,
	&goog_attr_rx_bad_packets_uni.dev_attr.attr,
	&goog_attr_rx_multicast_packets_uni.dev_attr.attr,
	&goog_attr_rx_broadcast_packets_uni.dev_attr.attr,
	&goog_attr_tx_good_packets_uni.dev_attr.attr,
	&goog_attr_tx_broadcast_packets_uni.dev_attr.attr,
	&goog_attr_tx_multicast_packets_uni.dev_attr.attr,
	NULL
};


static struct attribute_group goog_uni_stats = {
	.name = "unistats",
	.attrs = goog_uni_attrs,
};


// Stats for the ANI port.
static GOOG_ATTR(rx_good_packets, ani, goog_get_stat, ETH_MIB_GOOD_FRAMES_RECEIVED, MV_PON_PORT_ID);
static GOOG_ATTR(rx_bad_packets, ani, goog_get_stat, ETH_MIB_BAD_FRAMES_RECEIVED, MV_PON_PORT_ID);
static GOOG_ATTR(rx_broadcast_packets, ani, goog_get_stat, ETH_MIB_BROADCAST_FRAMES_RECEIVED, MV_PON_PORT_ID);
static GOOG_ATTR(rx_multicast_packets, ani, goog_get_stat, ETH_MIB_MULTICAST_FRAMES_RECEIVED, MV_PON_PORT_ID);
static GOOG_ATTR(tx_good_packets, ani, goog_get_stat, ETH_MIB_GOOD_FRAMES_SENT, MV_PON_PORT_ID);
static GOOG_ATTR(tx_broadcast_packets, ani, goog_get_stat, ETH_MIB_BROADCAST_FRAMES_SENT, MV_PON_PORT_ID);
static GOOG_ATTR(tx_multicast_packets, ani, goog_get_stat, ETH_MIB_MULTICAST_FRAMES_SENT, MV_PON_PORT_ID);

static struct attribute *goog_ani_attrs[] = {
	&goog_attr_rx_good_packets_ani.dev_attr.attr,
	&goog_attr_rx_bad_packets_ani.dev_attr.attr,
	&goog_attr_rx_multicast_packets_ani.dev_attr.attr,
	&goog_attr_rx_broadcast_packets_ani.dev_attr.attr,
	&goog_attr_tx_good_packets_ani.dev_attr.attr,
	&goog_attr_tx_broadcast_packets_ani.dev_attr.attr,
	&goog_attr_tx_multicast_packets_ani.dev_attr.attr,
	NULL
};

static struct attribute_group goog_ani_stats = {
	.name = "anistats",
	.attrs = goog_ani_attrs,
};

int __devinit goog_eth_sysfs_init(void)
{
	int err = 0;
	struct device *pd = NULL;

	pd = bus_find_device_by_name(&platform_bus_type, NULL, "neta");
	if (!pd) {
		platform_device_register_simple("neta", -1, NULL, 0);
		pd = bus_find_device_by_name(&platform_bus_type, NULL, "neta");
	}

	if (!pd) {
		printk(KERN_ERR"%s: cannot find neta device\n", __func__);
		pd = &platform_bus;
	}

	err = sysfs_create_group(&pd->kobj, &goog_uni_stats);
	if (err) {
		printk(KERN_INFO "sysfs group failed %d\n", err);
		goto out;
	}

	err = sysfs_create_group(&pd->kobj, &goog_ani_stats);
	if (err) {
		printk(KERN_INFO "sysfs group failed %d\n", err);
		goto out;
	}
out:
	return err;
}



module_init(goog_eth_sysfs_init);

MODULE_AUTHOR("jnewlin@google.com");
MODULE_DESCRIPTION("Readable netstats for Marvell 6601.");
MODULE_LICENSE("GPL");
