/*
 *  drivers/net/gianfar_ethtool.c
 *
 *  Gianfar Ethernet Driver
 *  Ethtool support for Gianfar Enet
 *  Based on e1000 ethtool support
 *
 *  Author: Andy Fleming
 *  Maintainer: Kumar Gala (kumar.gala@freescale.com)
 *
 *  Copyright (c) 2003,2004 Freescale Semiconductor, Inc.
 *
 *  This software may be used and distributed according to 
 *  the terms of the GNU Public License, Version 2, incorporated herein 
 *  by reference.
 */

#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/mm.h>

#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/crc32.h>
#include <asm/types.h>
#include <asm/uaccess.h>
#include <linux/ethtool.h>

#include "gianfar.h"

#define is_power_of_2(x)        ((x) != 0 && (((x) & ((x) - 1)) == 0))

extern int startup_gfar(struct net_device *dev);
extern void stop_gfar(struct net_device *dev);
extern void gfar_halt(struct net_device *dev);
extern void gfar_start(struct net_device *dev);
extern int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit);

static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy,
		     u64 * buf);
static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf);
static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals);
static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals);
static void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rvals);
static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rvals);
static void gfar_gdrvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo);

static char stat_gstrings[][ETH_GSTRING_LEN] = {
	"rx-dropped-by-kernel",
	"rx-large-frame-errors",
	"rx-short-frame-errors",
	"rx-non-octet-errors",
	"rx-crc-errors",
	"rx-overrun-errors",
	"rx-busy-errors",
	"rx-babbling-errors",
	"rx-truncated-frames",
	"ethernet-bus-error",
	"tx-babbling-errors",
	"tx-underrun-errors",
	"rx-skb-missing-errors",
	"tx-timeout-errors",
	"tx-rx-64-frames",
	"tx-rx-65-127-frames",
	"tx-rx-128-255-frames",
	"tx-rx-256-511-frames",
	"tx-rx-512-1023-frames",
	"tx-rx-1024-1518-frames",
	"tx-rx-1519-1522-good-vlan",
	"rx-bytes",
	"rx-packets",
	"rx-fcs-errors",
	"receive-multicast-packet",
	"receive-broadcast-packet",
	"rx-control-frame-packets",
	"rx-pause-frame-packets",
	"rx-unknown-op-code",
	"rx-alignment-error",
	"rx-frame-length-error",
	"rx-code-error",
	"rx-carrier-sense-error",
	"rx-undersize-packets",
	"rx-oversize-packets",
	"rx-fragmented-frames",
	"rx-jabber-frames",
	"rx-dropped-frames",
	"tx-byte-counter",
	"tx-packets",
	"tx-multicast-packets",
	"tx-broadcast-packets",
	"tx-pause-control-frames",
	"tx-deferral-packets",
	"tx-excessive-deferral-packets",
	"tx-single-collision-packets",
	"tx-multiple-collision-packets",
	"tx-late-collision-packets",
	"tx-excessive-collision-packets",
	"tx-total-collision",
	"reserved",
	"tx-dropped-frames",
	"tx-jabber-frames",
	"tx-fcs-errors",
	"tx-control-frames",
	"tx-oversize-frames",
	"tx-undersize-frames",
	"tx-fragmented-frames",
};

/* Fill in a buffer with the strings which correspond to the
 * stats */
static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf)
{
	struct gfar_private *priv = netdev_priv(dev);
	
	if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON)
		memcpy(buf, stat_gstrings, GFAR_STATS_LEN * ETH_GSTRING_LEN);
	else
		memcpy(buf, stat_gstrings,
				GFAR_EXTRA_STATS_LEN * ETH_GSTRING_LEN);
}

/* Fill in an array of 64-bit statistics from various sources.
 * This array will be appended to the end of the ethtool_stats
 * structure, and returned to user space
 */
static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy, u64 * buf)
{
	int i;
	struct gfar_private *priv = netdev_priv(dev);
	u64 *extra = (u64 *) & priv->extra_stats;

	if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON) {
		u32 *rmon = (u32 *) & priv->regs->rmon;
		struct gfar_stats *stats = (struct gfar_stats *) buf;

		for (i = 0; i < GFAR_RMON_LEN; i++)
			stats->rmon[i] = (u64) (rmon[i]);

		for (i = 0; i < GFAR_EXTRA_STATS_LEN; i++)
			stats->extra[i] = extra[i];
	} else
		for (i = 0; i < GFAR_EXTRA_STATS_LEN; i++)
			buf[i] = extra[i];
}

/* Returns the number of stats (and their corresponding strings) */
static int gfar_stats_count(struct net_device *dev)
{
	struct gfar_private *priv = netdev_priv(dev);

	if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON)
		return GFAR_STATS_LEN;
	else
		return GFAR_EXTRA_STATS_LEN;
}

/* Fills in the drvinfo structure with some basic info */
static void gfar_gdrvinfo(struct net_device *dev, struct
	      ethtool_drvinfo *drvinfo)
{
	strncpy(drvinfo->driver, DRV_NAME, GFAR_INFOSTR_LEN);
	strncpy(drvinfo->version, gfar_driver_version, GFAR_INFOSTR_LEN);
	strncpy(drvinfo->fw_version, "N/A", GFAR_INFOSTR_LEN);
	strncpy(drvinfo->bus_info, "N/A", GFAR_INFOSTR_LEN);
	drvinfo->n_stats = GFAR_STATS_LEN;
	drvinfo->testinfo_len = 0;
	drvinfo->regdump_len = 0;
	drvinfo->eedump_len = 0;
}

/* Return the current settings in the ethtool_cmd structure */
static int gfar_gsettings(struct net_device *dev, struct ethtool_cmd *cmd)
{
	struct gfar_private *priv = netdev_priv(dev);
	uint gigabit_support = 
		priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
			SUPPORTED_1000baseT_Full : 0;
	uint gigabit_advert = 
		priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
			ADVERTISED_1000baseT_Full: 0;

	cmd->supported = (SUPPORTED_10baseT_Half
			  | SUPPORTED_100baseT_Half
			  | SUPPORTED_100baseT_Full
			  | gigabit_support | SUPPORTED_Autoneg);

	/* For now, we always advertise everything */
	cmd->advertising = (ADVERTISED_10baseT_Half
			    | ADVERTISED_100baseT_Half
			    | ADVERTISED_100baseT_Full
			    | gigabit_advert | ADVERTISED_Autoneg);

	cmd->speed = priv->mii_info->speed;
	cmd->duplex = priv->mii_info->duplex;
	cmd->port = PORT_MII;
	cmd->phy_address = priv->mii_info->mii_id;
	cmd->transceiver = XCVR_EXTERNAL;
	cmd->autoneg = AUTONEG_ENABLE;
	cmd->maxtxpkt = priv->txcount;
	cmd->maxrxpkt = priv->rxcount;

	return 0;
}

/* Return the length of the register structure */
static int gfar_reglen(struct net_device *dev)
{
	return sizeof (struct gfar);
}

/* Return a dump of the GFAR register space */
static void gfar_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf)
{
	int i;
	struct gfar_private *priv = netdev_priv(dev);
	u32 *theregs = (u32 *) priv->regs;
	u32 *buf = (u32 *) regbuf;

	for (i = 0; i < sizeof (struct gfar) / sizeof (u32); i++)
		buf[i] = theregs[i];
}

/* Convert microseconds to ethernet clock ticks, which changes
 * depending on what speed the controller is running at */
static unsigned int gfar_usecs2ticks(struct gfar_private *priv, unsigned int usecs)
{
	unsigned int count;

	/* The timer is different, depending on the interface speed */
	switch (priv->mii_info->speed) {
	case 1000:
		count = GFAR_GBIT_TIME;
		break;
	case 100:
		count = GFAR_100_TIME;
		break;
	case 10:
	default:
		count = GFAR_10_TIME;
		break;
	}

	/* Make sure we return a number greater than 0
	 * if usecs > 0 */
	return ((usecs * 1000 + count - 1) / count);
}

/* Convert ethernet clock ticks to microseconds */
static unsigned int gfar_ticks2usecs(struct gfar_private *priv, unsigned int ticks)
{
	unsigned int count;

	/* The timer is different, depending on the interface speed */
	switch (priv->mii_info->speed) {
	case 1000:
		count = GFAR_GBIT_TIME;
		break;
	case 100:
		count = GFAR_100_TIME;
		break;
	case 10:
	default:
		count = GFAR_10_TIME;
		break;
	}

	/* Make sure we return a number greater than 0 */
	/* if ticks is > 0 */
	return ((ticks * count) / 1000);
}

/* Get the coalescing parameters, and put them in the cvals
 * structure.  */
static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals)
{
	struct gfar_private *priv = netdev_priv(dev);
	
	if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE))
		return -EOPNOTSUPP;

	cvals->rx_coalesce_usecs = gfar_ticks2usecs(priv, priv->rxtime);
	cvals->rx_max_coalesced_frames = priv->rxcount;

	cvals->tx_coalesce_usecs = gfar_ticks2usecs(priv, priv->txtime);
	cvals->tx_max_coalesced_frames = priv->txcount;

	cvals->use_adaptive_rx_coalesce = 0;
	cvals->use_adaptive_tx_coalesce = 0;

	cvals->pkt_rate_low = 0;
	cvals->rx_coalesce_usecs_low = 0;
	cvals->rx_max_coalesced_frames_low = 0;
	cvals->tx_coalesce_usecs_low = 0;
	cvals->tx_max_coalesced_frames_low = 0;

	/* When the packet rate is below pkt_rate_high but above
	 * pkt_rate_low (both measured in packets per second) the
	 * normal {rx,tx}_* coalescing parameters are used.
	 */

	/* When the packet rate is (measured in packets per second)
	 * is above pkt_rate_high, the {rx,tx}_*_high parameters are
	 * used.
	 */
	cvals->pkt_rate_high = 0;
	cvals->rx_coalesce_usecs_high = 0;
	cvals->rx_max_coalesced_frames_high = 0;
	cvals->tx_coalesce_usecs_high = 0;
	cvals->tx_max_coalesced_frames_high = 0;

	/* How often to do adaptive coalescing packet rate sampling,
	 * measured in seconds.  Must not be zero.
	 */
	cvals->rate_sample_interval = 0;

	return 0;
}

/* Change the coalescing values.
 * Both cvals->*_usecs and cvals->*_frames have to be > 0
 * in order for coalescing to be active
 */
static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals)
{
	struct gfar_private *priv = netdev_priv(dev);

	if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE))
		return -EOPNOTSUPP;

	/* Set up rx coalescing */
	if ((cvals->rx_coalesce_usecs == 0) ||
	    (cvals->rx_max_coalesced_frames == 0))
		priv->rxcoalescing = 0;
	else
		priv->rxcoalescing = 1;

	priv->rxtime = gfar_usecs2ticks(priv, cvals->rx_coalesce_usecs);
	priv->rxcount = cvals->rx_max_coalesced_frames;

	/* Set up tx coalescing */
	if ((cvals->tx_coalesce_usecs == 0) ||
	    (cvals->tx_max_coalesced_frames == 0))
		priv->txcoalescing = 0;
	else
		priv->txcoalescing = 1;

	priv->txtime = gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs);
	priv->txcount = cvals->tx_max_coalesced_frames;

	if (priv->rxcoalescing)
		gfar_write(&priv->regs->rxic,
			   mk_ic_value(priv->rxcount, priv->rxtime));
	else
		gfar_write(&priv->regs->rxic, 0);

	if (priv->txcoalescing)
		gfar_write(&priv->regs->txic,
			   mk_ic_value(priv->txcount, priv->txtime));
	else
		gfar_write(&priv->regs->txic, 0);

	return 0;
}

/* Fills in rvals with the current ring parameters.  Currently,
 * rx, rx_mini, and rx_jumbo rings are the same size, as mini and
 * jumbo are ignored by the driver */
static void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rvals)
{
	struct gfar_private *priv = netdev_priv(dev);

	rvals->rx_max_pending = GFAR_RX_MAX_RING_SIZE;
	rvals->rx_mini_max_pending = GFAR_RX_MAX_RING_SIZE;
	rvals->rx_jumbo_max_pending = GFAR_RX_MAX_RING_SIZE;
	rvals->tx_max_pending = GFAR_TX_MAX_RING_SIZE;

	/* Values changeable by the user.  The valid values are
	 * in the range 1 to the "*_max_pending" counterpart above.
	 */
	rvals->rx_pending = priv->rx_ring_size;
	rvals->rx_mini_pending = priv->rx_ring_size;
	rvals->rx_jumbo_pending = priv->rx_ring_size;
	rvals->tx_pending = priv->tx_ring_size;
}

/* Change the current ring parameters, stopping the controller if
 * necessary so that we don't mess things up while we're in
 * motion.  We wait for the ring to be clean before reallocating
 * the rings. */
static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rvals)
{
	struct gfar_private *priv = netdev_priv(dev);
	int err = 0;

	if (rvals->rx_pending > GFAR_RX_MAX_RING_SIZE)
		return -EINVAL;

	if (!is_power_of_2(rvals->rx_pending)) {
		printk("%s: Ring sizes must be a power of 2\n",
				dev->name);
		return -EINVAL;
	}

	if (rvals->tx_pending > GFAR_TX_MAX_RING_SIZE)
		return -EINVAL;

	if (!is_power_of_2(rvals->tx_pending)) {
		printk("%s: Ring sizes must be a power of 2\n",
				dev->name);
		return -EINVAL;
	}

	if (dev->flags & IFF_UP) {
		unsigned long flags;

		/* Halt TX and RX, and process the frames which
		 * have already been received */
		spin_lock_irqsave(&priv->lock, flags);
		gfar_halt(dev);
		gfar_clean_rx_ring(dev, priv->rx_ring_size);
		spin_unlock_irqrestore(&priv->lock, flags);

		/* Now we take down the rings to rebuild them */
		stop_gfar(dev);
	}

	/* Change the size */
	priv->rx_ring_size = rvals->rx_pending;
	priv->tx_ring_size = rvals->tx_pending;

	/* Rebuild the rings with the new size */
	if (dev->flags & IFF_UP)
		err = startup_gfar(dev);

	return err;
}

static int gfar_set_rx_csum(struct net_device *dev, uint32_t data)
{
	struct gfar_private *priv = netdev_priv(dev);
	int err = 0;

	if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
		return -EOPNOTSUPP;

	if (dev->flags & IFF_UP) {
		unsigned long flags;

		/* Halt TX and RX, and process the frames which
		 * have already been received */
		spin_lock_irqsave(&priv->lock, flags);
		gfar_halt(dev);
		gfar_clean_rx_ring(dev, priv->rx_ring_size);
		spin_unlock_irqrestore(&priv->lock, flags);

		/* Now we take down the rings to rebuild them */
		stop_gfar(dev);
	}

	priv->rx_csum_enable = data;

	if (dev->flags & IFF_UP)
		err = startup_gfar(dev);

	return err;
}

static uint32_t gfar_get_rx_csum(struct net_device *dev)
{
	struct gfar_private *priv = netdev_priv(dev);

	if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
		return 0;

	return priv->rx_csum_enable;
}

static int gfar_set_tx_csum(struct net_device *dev, uint32_t data)
{
	unsigned long flags;
	struct gfar_private *priv = netdev_priv(dev);

	if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
		return -EOPNOTSUPP;

	spin_lock_irqsave(&priv->lock, flags);
	gfar_halt(dev);

	if (data)
		dev->features |= NETIF_F_IP_CSUM;
	else
		dev->features &= ~NETIF_F_IP_CSUM;

	gfar_start(dev);
	spin_unlock_irqrestore(&priv->lock, flags);

	return 0;
}

static uint32_t gfar_get_tx_csum(struct net_device *dev)
{
	struct gfar_private *priv = netdev_priv(dev);

	if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
		return 0;

	return (dev->features & NETIF_F_IP_CSUM) != 0;
}

static uint32_t gfar_get_msglevel(struct net_device *dev)
{       
	struct gfar_private *priv = netdev_priv(dev);
	return priv->msg_enable;
}       
        
static void gfar_set_msglevel(struct net_device *dev, uint32_t data)
{       
	struct gfar_private *priv = netdev_priv(dev);
	priv->msg_enable = data;
}


struct ethtool_ops gfar_ethtool_ops = {
	.get_settings = gfar_gsettings,
	.get_drvinfo = gfar_gdrvinfo,
	.get_regs_len = gfar_reglen,
	.get_regs = gfar_get_regs,
	.get_link = ethtool_op_get_link,
	.get_coalesce = gfar_gcoalesce,
	.set_coalesce = gfar_scoalesce,
	.get_ringparam = gfar_gringparam,
	.set_ringparam = gfar_sringparam,
	.get_strings = gfar_gstrings,
	.get_stats_count = gfar_stats_count,
	.get_ethtool_stats = gfar_fill_stats,
	.get_rx_csum = gfar_get_rx_csum,
	.get_tx_csum = gfar_get_tx_csum,
	.set_rx_csum = gfar_set_rx_csum,
	.set_tx_csum = gfar_set_tx_csum,
	.get_msglevel = gfar_get_msglevel,
	.set_msglevel = gfar_set_msglevel,
};
