/*
 *  drivers/net/gianfar_ethtool.c
 *
 *  Gianfar Ethernet Driver
 *  Ethtool support for Gianfar Enet
 *  Based on e1000 ethtool support
 *
 *  Author: Andy Fleming
 *  Maintainer: Kumar Gala
 *  Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com>
 *
 *  Copyright 2003-2006, 2008-2009, 2011 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.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/errno.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/crc32.h>
#include <asm/types.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/phy.h>
#include <linux/sort.h>

#include "gianfar.h"

extern void gfar_start(struct net_device *dev);
extern int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit);

#define GFAR_MAX_COAL_USECS 0xffff
#define GFAR_MAX_COAL_FRAMES 0xff
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->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);
	struct gfar __iomem *regs = priv->gfargrp[0].regs;
	u64 *extra = (u64 *) & priv->extra_stats;

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

		for (i = 0; i < GFAR_RMON_LEN; i++)
			stats->rmon[i] = (u64) gfar_read(&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];
}

static int gfar_sset_count(struct net_device *dev, int sset)
{
	struct gfar_private *priv = netdev_priv(dev);

	switch (sset) {
	case ETH_SS_STATS:
		if (priv->device_flags & FSL_GIANFAR_DEV_HAS_RMON)
			return GFAR_STATS_LEN;
		else
			return GFAR_EXTRA_STATS_LEN;
	default:
		return -EOPNOTSUPP;
	}
}

/* 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->regdump_len = 0;
	drvinfo->eedump_len = 0;
}


static int gfar_ssettings(struct net_device *dev, struct ethtool_cmd *cmd)
{
	struct gfar_private *priv = netdev_priv(dev);
	struct phy_device *phydev = priv->phydev;

	if (NULL == phydev)
		return -ENODEV;

	return phy_ethtool_sset(phydev, cmd);
}


/* 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);
	struct phy_device *phydev = priv->phydev;
	struct gfar_priv_rx_q *rx_queue = NULL;
	struct gfar_priv_tx_q *tx_queue = NULL;

	if (NULL == phydev)
		return -ENODEV;
	tx_queue = priv->tx_queue[0];
	rx_queue = priv->rx_queue[0];

	/* etsec-1.7 and older versions have only one txic
	 * and rxic regs although they support multiple queues */
	cmd->maxtxpkt = get_icft_value(tx_queue->txic);
	cmd->maxrxpkt = get_icft_value(rx_queue->rxic);

	return phy_ethtool_gset(phydev, cmd);
}

/* 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 __iomem *theregs = (u32 __iomem *) priv->gfargrp[0].regs;
	u32 *buf = (u32 *) regbuf;

	for (i = 0; i < sizeof (struct gfar) / sizeof (u32); i++)
		buf[i] = gfar_read(&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->phydev->speed) {
	case SPEED_1000:
		count = GFAR_GBIT_TIME;
		break;
	case SPEED_100:
		count = GFAR_100_TIME;
		break;
	case SPEED_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->phydev->speed) {
	case SPEED_1000:
		count = GFAR_GBIT_TIME;
		break;
	case SPEED_100:
		count = GFAR_100_TIME;
		break;
	case SPEED_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);
	struct gfar_priv_rx_q *rx_queue = NULL;
	struct gfar_priv_tx_q *tx_queue = NULL;
	unsigned long rxtime;
	unsigned long rxcount;
	unsigned long txtime;
	unsigned long txcount;

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

	if (NULL == priv->phydev)
		return -ENODEV;

	rx_queue = priv->rx_queue[0];
	tx_queue = priv->tx_queue[0];

	rxtime  = get_ictt_value(rx_queue->rxic);
	rxcount = get_icft_value(rx_queue->rxic);
	txtime  = get_ictt_value(tx_queue->txic);
	txcount = get_icft_value(tx_queue->txic);
	cvals->rx_coalesce_usecs = gfar_ticks2usecs(priv, rxtime);
	cvals->rx_max_coalesced_frames = rxcount;

	cvals->tx_coalesce_usecs = gfar_ticks2usecs(priv, txtime);
	cvals->tx_max_coalesced_frames = 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);
	int i = 0;

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

	/* Set up rx coalescing */
	/* As of now, we will enable/disable coalescing for all
	 * queues together in case of eTSEC2, this will be modified
	 * along with the ethtool interface */
	if ((cvals->rx_coalesce_usecs == 0) ||
	    (cvals->rx_max_coalesced_frames == 0)) {
		for (i = 0; i < priv->num_rx_queues; i++)
			priv->rx_queue[i]->rxcoalescing = 0;
	} else {
		for (i = 0; i < priv->num_rx_queues; i++)
			priv->rx_queue[i]->rxcoalescing = 1;
	}

	if (NULL == priv->phydev)
		return -ENODEV;

	/* Check the bounds of the values */
	if (cvals->rx_coalesce_usecs > GFAR_MAX_COAL_USECS) {
		pr_info("Coalescing is limited to %d microseconds\n",
			GFAR_MAX_COAL_USECS);
		return -EINVAL;
	}

	if (cvals->rx_max_coalesced_frames > GFAR_MAX_COAL_FRAMES) {
		pr_info("Coalescing is limited to %d frames\n",
			GFAR_MAX_COAL_FRAMES);
		return -EINVAL;
	}

	for (i = 0; i < priv->num_rx_queues; i++) {
		priv->rx_queue[i]->rxic = mk_ic_value(
			cvals->rx_max_coalesced_frames,
			gfar_usecs2ticks(priv, cvals->rx_coalesce_usecs));
	}

	/* Set up tx coalescing */
	if ((cvals->tx_coalesce_usecs == 0) ||
	    (cvals->tx_max_coalesced_frames == 0)) {
		for (i = 0; i < priv->num_tx_queues; i++)
			priv->tx_queue[i]->txcoalescing = 0;
	} else {
		for (i = 0; i < priv->num_tx_queues; i++)
			priv->tx_queue[i]->txcoalescing = 1;
	}

	/* Check the bounds of the values */
	if (cvals->tx_coalesce_usecs > GFAR_MAX_COAL_USECS) {
		pr_info("Coalescing is limited to %d microseconds\n",
			GFAR_MAX_COAL_USECS);
		return -EINVAL;
	}

	if (cvals->tx_max_coalesced_frames > GFAR_MAX_COAL_FRAMES) {
		pr_info("Coalescing is limited to %d frames\n",
			GFAR_MAX_COAL_FRAMES);
		return -EINVAL;
	}

	for (i = 0; i < priv->num_tx_queues; i++) {
		priv->tx_queue[i]->txic = mk_ic_value(
			cvals->tx_max_coalesced_frames,
			gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs));
	}

	gfar_configure_coalescing(priv, 0xFF, 0xFF);

	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);
	struct gfar_priv_tx_q *tx_queue = NULL;
	struct gfar_priv_rx_q *rx_queue = NULL;

	tx_queue = priv->tx_queue[0];
	rx_queue = priv->rx_queue[0];

	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 = rx_queue->rx_ring_size;
	rvals->rx_mini_pending = rx_queue->rx_ring_size;
	rvals->rx_jumbo_pending = rx_queue->rx_ring_size;
	rvals->tx_pending = tx_queue->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, i = 0;

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

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

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

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


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

		/* Halt TX and RX, and process the frames which
		 * have already been received */
		local_irq_save(flags);
		lock_tx_qs(priv);
		lock_rx_qs(priv);

		gfar_halt(dev);

		unlock_rx_qs(priv);
		unlock_tx_qs(priv);
		local_irq_restore(flags);

		for (i = 0; i < priv->num_rx_queues; i++)
			gfar_clean_rx_ring(priv->rx_queue[i],
					priv->rx_queue[i]->rx_ring_size);

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

	/* Change the size */
	for (i = 0; i < priv->num_rx_queues; i++) {
		priv->rx_queue[i]->rx_ring_size = rvals->rx_pending;
		priv->tx_queue[i]->tx_ring_size = rvals->tx_pending;
		priv->tx_queue[i]->num_txbdfree = priv->tx_queue[i]->tx_ring_size;
	}

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

int gfar_set_features(struct net_device *dev, u32 features)
{
	struct gfar_private *priv = netdev_priv(dev);
	unsigned long flags;
	int err = 0, i = 0;
	u32 changed = dev->features ^ features;

	if (!(changed & NETIF_F_RXCSUM))
		return 0;

	if (dev->flags & IFF_UP) {
		/* Halt TX and RX, and process the frames which
		 * have already been received */
		local_irq_save(flags);
		lock_tx_qs(priv);
		lock_rx_qs(priv);

		gfar_halt(dev);

		unlock_tx_qs(priv);
		unlock_rx_qs(priv);
		local_irq_restore(flags);

		for (i = 0; i < priv->num_rx_queues; i++)
			gfar_clean_rx_ring(priv->rx_queue[i],
					priv->rx_queue[i]->rx_ring_size);

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

		dev->features = features;

		err = startup_gfar(dev);
		netif_tx_wake_all_queues(dev);
	}
	return err;
}

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;
}

#ifdef CONFIG_PM
static void gfar_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
	struct gfar_private *priv = netdev_priv(dev);

	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) {
		wol->supported = WAKE_MAGIC;
		wol->wolopts = priv->wol_en ? WAKE_MAGIC : 0;
	} else {
		wol->supported = wol->wolopts = 0;
	}
}

static int gfar_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
	struct gfar_private *priv = netdev_priv(dev);
	unsigned long flags;

	if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) &&
	    wol->wolopts != 0)
		return -EINVAL;

	if (wol->wolopts & ~WAKE_MAGIC)
		return -EINVAL;

	device_set_wakeup_enable(&dev->dev, wol->wolopts & WAKE_MAGIC);

	spin_lock_irqsave(&priv->bflock, flags);
	priv->wol_en =  !!device_may_wakeup(&dev->dev);
	spin_unlock_irqrestore(&priv->bflock, flags);

	return 0;
}
#endif

static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow)
{
	u32 fcr = 0x0, fpr = FPR_FILER_MASK;

	if (ethflow & RXH_L2DA) {
		fcr = RQFCR_PID_DAH |RQFCR_CMP_NOMATCH |
			RQFCR_HASH | RQFCR_AND | RQFCR_HASHTBL_0;
		priv->ftp_rqfpr[priv->cur_filer_idx] = fpr;
		priv->ftp_rqfcr[priv->cur_filer_idx] = fcr;
		gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
		priv->cur_filer_idx = priv->cur_filer_idx - 1;

		fcr = RQFCR_PID_DAL | RQFCR_AND | RQFCR_CMP_NOMATCH |
				RQFCR_HASH | RQFCR_AND | RQFCR_HASHTBL_0;
		priv->ftp_rqfpr[priv->cur_filer_idx] = fpr;
		priv->ftp_rqfcr[priv->cur_filer_idx] = fcr;
		gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
		priv->cur_filer_idx = priv->cur_filer_idx - 1;
	}

	if (ethflow & RXH_VLAN) {
		fcr = RQFCR_PID_VID | RQFCR_CMP_NOMATCH | RQFCR_HASH |
				RQFCR_AND | RQFCR_HASHTBL_0;
		gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
		priv->ftp_rqfpr[priv->cur_filer_idx] = fpr;
		priv->ftp_rqfcr[priv->cur_filer_idx] = fcr;
		priv->cur_filer_idx = priv->cur_filer_idx - 1;
	}

	if (ethflow & RXH_IP_SRC) {
		fcr = RQFCR_PID_SIA | RQFCR_CMP_NOMATCH | RQFCR_HASH |
			RQFCR_AND | RQFCR_HASHTBL_0;
		priv->ftp_rqfpr[priv->cur_filer_idx] = fpr;
		priv->ftp_rqfcr[priv->cur_filer_idx] = fcr;
		gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
		priv->cur_filer_idx = priv->cur_filer_idx - 1;
	}

	if (ethflow & (RXH_IP_DST)) {
		fcr = RQFCR_PID_DIA | RQFCR_CMP_NOMATCH | RQFCR_HASH |
			RQFCR_AND | RQFCR_HASHTBL_0;
		priv->ftp_rqfpr[priv->cur_filer_idx] = fpr;
		priv->ftp_rqfcr[priv->cur_filer_idx] = fcr;
		gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
		priv->cur_filer_idx = priv->cur_filer_idx - 1;
	}

	if (ethflow & RXH_L3_PROTO) {
		fcr = RQFCR_PID_L4P | RQFCR_CMP_NOMATCH | RQFCR_HASH |
			RQFCR_AND | RQFCR_HASHTBL_0;
		priv->ftp_rqfpr[priv->cur_filer_idx] = fpr;
		priv->ftp_rqfcr[priv->cur_filer_idx] = fcr;
		gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
		priv->cur_filer_idx = priv->cur_filer_idx - 1;
	}

	if (ethflow & RXH_L4_B_0_1) {
		fcr = RQFCR_PID_SPT | RQFCR_CMP_NOMATCH | RQFCR_HASH |
			RQFCR_AND | RQFCR_HASHTBL_0;
		priv->ftp_rqfpr[priv->cur_filer_idx] = fpr;
		priv->ftp_rqfcr[priv->cur_filer_idx] = fcr;
		gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
		priv->cur_filer_idx = priv->cur_filer_idx - 1;
	}

	if (ethflow & RXH_L4_B_2_3) {
		fcr = RQFCR_PID_DPT | RQFCR_CMP_NOMATCH | RQFCR_HASH |
			RQFCR_AND | RQFCR_HASHTBL_0;
		priv->ftp_rqfpr[priv->cur_filer_idx] = fpr;
		priv->ftp_rqfcr[priv->cur_filer_idx] = fcr;
		gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
		priv->cur_filer_idx = priv->cur_filer_idx - 1;
	}
}

static int gfar_ethflow_to_filer_table(struct gfar_private *priv, u64 ethflow, u64 class)
{
	unsigned int last_rule_idx = priv->cur_filer_idx;
	unsigned int cmp_rqfpr;
	unsigned int local_rqfpr[MAX_FILER_IDX + 1];
	unsigned int local_rqfcr[MAX_FILER_IDX + 1];
	int i = 0x0, k = 0x0;
	int j = MAX_FILER_IDX, l = 0x0;

	switch (class) {
	case TCP_V4_FLOW:
		cmp_rqfpr = RQFPR_IPV4 |RQFPR_TCP;
		break;
	case UDP_V4_FLOW:
		cmp_rqfpr = RQFPR_IPV4 |RQFPR_UDP;
		break;
	case TCP_V6_FLOW:
		cmp_rqfpr = RQFPR_IPV6 |RQFPR_TCP;
		break;
	case UDP_V6_FLOW:
		cmp_rqfpr = RQFPR_IPV6 |RQFPR_UDP;
		break;
	default:
		pr_err("Right now this class is not supported\n");
		return 0;
	}

	for (i = 0; i < MAX_FILER_IDX + 1; i++) {
		local_rqfpr[j] = priv->ftp_rqfpr[i];
		local_rqfcr[j] = priv->ftp_rqfcr[i];
		j--;
		if ((priv->ftp_rqfcr[i] == (RQFCR_PID_PARSE |
			RQFCR_CLE |RQFCR_AND)) &&
			(priv->ftp_rqfpr[i] == cmp_rqfpr))
			break;
	}

	if (i == MAX_FILER_IDX + 1) {
		pr_err("No parse rule found, can't create hash rules\n");
		return 0;
	}

	/* If a match was found, then it begins the starting of a cluster rule
	 * if it was already programmed, we need to overwrite these rules
	 */
	for (l = i+1; l < MAX_FILER_IDX; l++) {
		if ((priv->ftp_rqfcr[l] & RQFCR_CLE) &&
			!(priv->ftp_rqfcr[l] & RQFCR_AND)) {
			priv->ftp_rqfcr[l] = RQFCR_CLE | RQFCR_CMP_EXACT |
				RQFCR_HASHTBL_0 | RQFCR_PID_MASK;
			priv->ftp_rqfpr[l] = FPR_FILER_MASK;
			gfar_write_filer(priv, l, priv->ftp_rqfcr[l],
				priv->ftp_rqfpr[l]);
			break;
		}

		if (!(priv->ftp_rqfcr[l] & RQFCR_CLE) &&
			(priv->ftp_rqfcr[l] & RQFCR_AND))
			continue;
		else {
			local_rqfpr[j] = priv->ftp_rqfpr[l];
			local_rqfcr[j] = priv->ftp_rqfcr[l];
			j--;
		}
	}

	priv->cur_filer_idx = l - 1;
	last_rule_idx = l;

	/* hash rules */
	ethflow_to_filer_rules(priv, ethflow);

	/* Write back the popped out rules again */
	for (k = j+1; k < MAX_FILER_IDX; k++) {
		priv->ftp_rqfpr[priv->cur_filer_idx] = local_rqfpr[k];
		priv->ftp_rqfcr[priv->cur_filer_idx] = local_rqfcr[k];
		gfar_write_filer(priv, priv->cur_filer_idx,
				local_rqfcr[k], local_rqfpr[k]);
		if (!priv->cur_filer_idx)
			break;
		priv->cur_filer_idx = priv->cur_filer_idx - 1;
	}

	return 1;
}

static int gfar_set_hash_opts(struct gfar_private *priv, struct ethtool_rxnfc *cmd)
{
	/* write the filer rules here */
	if (!gfar_ethflow_to_filer_table(priv, cmd->data, cmd->flow_type))
		return -EINVAL;

	return 0;
}

static int gfar_check_filer_hardware(struct gfar_private *priv)
{
	struct gfar __iomem *regs = NULL;
	u32 i;

	regs = priv->gfargrp[0].regs;

	/* Check if we are in FIFO mode */
	i = gfar_read(&regs->ecntrl);
	i &= ECNTRL_FIFM;
	if (i == ECNTRL_FIFM) {
		netdev_notice(priv->ndev, "Interface in FIFO mode\n");
		i = gfar_read(&regs->rctrl);
		i &= RCTRL_PRSDEP_MASK | RCTRL_PRSFM;
		if (i == (RCTRL_PRSDEP_MASK | RCTRL_PRSFM)) {
			netdev_info(priv->ndev,
					"Receive Queue Filtering enabled\n");
		} else {
			netdev_warn(priv->ndev,
					"Receive Queue Filtering disabled\n");
			return -EOPNOTSUPP;
		}
	}
	/* Or in standard mode */
	else {
		i = gfar_read(&regs->rctrl);
		i &= RCTRL_PRSDEP_MASK;
		if (i == RCTRL_PRSDEP_MASK) {
			netdev_info(priv->ndev,
					"Receive Queue Filtering enabled\n");
		} else {
			netdev_warn(priv->ndev,
					"Receive Queue Filtering disabled\n");
			return -EOPNOTSUPP;
		}
	}

	/* Sets the properties for arbitrary filer rule
	 * to the first 4 Layer 4 Bytes */
	regs->rbifx = 0xC0C1C2C3;
	return 0;
}

static int gfar_comp_asc(const void *a, const void *b)
{
	return memcmp(a, b, 4);
}

static int gfar_comp_desc(const void *a, const void *b)
{
	return -memcmp(a, b, 4);
}

static void gfar_swap(void *a, void *b, int size)
{
	u32 *_a = a;
	u32 *_b = b;

	swap(_a[0], _b[0]);
	swap(_a[1], _b[1]);
	swap(_a[2], _b[2]);
	swap(_a[3], _b[3]);
}

/* Write a mask to filer cache */
static void gfar_set_mask(u32 mask, struct filer_table *tab)
{
	tab->fe[tab->index].ctrl = RQFCR_AND | RQFCR_PID_MASK | RQFCR_CMP_EXACT;
	tab->fe[tab->index].prop = mask;
	tab->index++;
}

/* Sets parse bits (e.g. IP or TCP) */
static void gfar_set_parse_bits(u32 value, u32 mask, struct filer_table *tab)
{
	gfar_set_mask(mask, tab);
	tab->fe[tab->index].ctrl = RQFCR_CMP_EXACT | RQFCR_PID_PARSE
			| RQFCR_AND;
	tab->fe[tab->index].prop = value;
	tab->index++;
}

static void gfar_set_general_attribute(u32 value, u32 mask, u32 flag,
		struct filer_table *tab)
{
	gfar_set_mask(mask, tab);
	tab->fe[tab->index].ctrl = RQFCR_CMP_EXACT | RQFCR_AND | flag;
	tab->fe[tab->index].prop = value;
	tab->index++;
}

/*
 * For setting a tuple of value and mask of type flag
 * Example:
 * IP-Src = 10.0.0.0/255.0.0.0
 * value: 0x0A000000 mask: FF000000 flag: RQFPR_IPV4
 *
 * Ethtool gives us a value=0 and mask=~0 for don't care a tuple
 * For a don't care mask it gives us a 0
 *
 * The check if don't care and the mask adjustment if mask=0 is done for VLAN
 * and MAC stuff on an upper level (due to missing information on this level).
 * For these guys we can discard them if they are value=0 and mask=0.
 *
 * Further the all masks are one-padded for better hardware efficiency.
 */
static void gfar_set_attribute(u32 value, u32 mask, u32 flag,
		struct filer_table *tab)
{
	switch (flag) {
	/* 3bit */
	case RQFCR_PID_PRI:
		if (!(value | mask))
			return;
		mask |= RQFCR_PID_PRI_MASK;
		break;
		/* 8bit */
	case RQFCR_PID_L4P:
	case RQFCR_PID_TOS:
		if (!~(mask | RQFCR_PID_L4P_MASK))
			return;
		if (!mask)
			mask = ~0;
		else
			mask |= RQFCR_PID_L4P_MASK;
		break;
		/* 12bit */
	case RQFCR_PID_VID:
		if (!(value | mask))
			return;
		mask |= RQFCR_PID_VID_MASK;
		break;
		/* 16bit */
	case RQFCR_PID_DPT:
	case RQFCR_PID_SPT:
	case RQFCR_PID_ETY:
		if (!~(mask | RQFCR_PID_PORT_MASK))
			return;
		if (!mask)
			mask = ~0;
		else
			mask |= RQFCR_PID_PORT_MASK;
		break;
		/* 24bit */
	case RQFCR_PID_DAH:
	case RQFCR_PID_DAL:
	case RQFCR_PID_SAH:
	case RQFCR_PID_SAL:
		if (!(value | mask))
			return;
		mask |= RQFCR_PID_MAC_MASK;
		break;
		/* for all real 32bit masks */
	default:
		if (!~mask)
			return;
		if (!mask)
			mask = ~0;
		break;
	}
	gfar_set_general_attribute(value, mask, flag, tab);
}

/* Translates value and mask for UDP, TCP or SCTP */
static void gfar_set_basic_ip(struct ethtool_tcpip4_spec *value,
		struct ethtool_tcpip4_spec *mask, struct filer_table *tab)
{
	gfar_set_attribute(value->ip4src, mask->ip4src, RQFCR_PID_SIA, tab);
	gfar_set_attribute(value->ip4dst, mask->ip4dst, RQFCR_PID_DIA, tab);
	gfar_set_attribute(value->pdst, mask->pdst, RQFCR_PID_DPT, tab);
	gfar_set_attribute(value->psrc, mask->psrc, RQFCR_PID_SPT, tab);
	gfar_set_attribute(value->tos, mask->tos, RQFCR_PID_TOS, tab);
}

/* Translates value and mask for RAW-IP4 */
static void gfar_set_user_ip(struct ethtool_usrip4_spec *value,
		struct ethtool_usrip4_spec *mask, struct filer_table *tab)
{
	gfar_set_attribute(value->ip4src, mask->ip4src, RQFCR_PID_SIA, tab);
	gfar_set_attribute(value->ip4dst, mask->ip4dst, RQFCR_PID_DIA, tab);
	gfar_set_attribute(value->tos, mask->tos, RQFCR_PID_TOS, tab);
	gfar_set_attribute(value->proto, mask->proto, RQFCR_PID_L4P, tab);
	gfar_set_attribute(value->l4_4_bytes, mask->l4_4_bytes, RQFCR_PID_ARB,
			tab);

}

/* Translates value and mask for ETHER spec */
static void gfar_set_ether(struct ethhdr *value, struct ethhdr *mask,
		struct filer_table *tab)
{
	u32 upper_temp_mask = 0;
	u32 lower_temp_mask = 0;
	/* Source address */
	if (!is_broadcast_ether_addr(mask->h_source)) {

		if (is_zero_ether_addr(mask->h_source)) {
			upper_temp_mask = 0xFFFFFFFF;
			lower_temp_mask = 0xFFFFFFFF;
		} else {
			upper_temp_mask = mask->h_source[0] << 16
					| mask->h_source[1] << 8
					| mask->h_source[2];
			lower_temp_mask = mask->h_source[3] << 16
					| mask->h_source[4] << 8
					| mask->h_source[5];
		}
		/* Upper 24bit */
		gfar_set_attribute(
				value->h_source[0] << 16 | value->h_source[1]
						<< 8 | value->h_source[2],
				upper_temp_mask, RQFCR_PID_SAH, tab);
		/* And the same for the lower part */
		gfar_set_attribute(
				value->h_source[3] << 16 | value->h_source[4]
						<< 8 | value->h_source[5],
				lower_temp_mask, RQFCR_PID_SAL, tab);
	}
	/* Destination address */
	if (!is_broadcast_ether_addr(mask->h_dest)) {

		/* Special for destination is limited broadcast */
		if ((is_broadcast_ether_addr(value->h_dest)
				&& is_zero_ether_addr(mask->h_dest))) {
			gfar_set_parse_bits(RQFPR_EBC, RQFPR_EBC, tab);
		} else {

			if (is_zero_ether_addr(mask->h_dest)) {
				upper_temp_mask = 0xFFFFFFFF;
				lower_temp_mask = 0xFFFFFFFF;
			} else {
				upper_temp_mask = mask->h_dest[0] << 16
						| mask->h_dest[1] << 8
						| mask->h_dest[2];
				lower_temp_mask = mask->h_dest[3] << 16
						| mask->h_dest[4] << 8
						| mask->h_dest[5];
			}

			/* Upper 24bit */
			gfar_set_attribute(
					value->h_dest[0] << 16
							| value->h_dest[1] << 8
							| value->h_dest[2],
					upper_temp_mask, RQFCR_PID_DAH, tab);
			/* And the same for the lower part */
			gfar_set_attribute(
					value->h_dest[3] << 16
							| value->h_dest[4] << 8
							| value->h_dest[5],
					lower_temp_mask, RQFCR_PID_DAL, tab);
		}
	}

	gfar_set_attribute(value->h_proto, mask->h_proto, RQFCR_PID_ETY, tab);

}

/* Convert a rule to binary filter format of gianfar */
static int gfar_convert_to_filer(struct ethtool_rx_flow_spec *rule,
		struct filer_table *tab)
{
	u32 vlan = 0, vlan_mask = 0;
	u32 id = 0, id_mask = 0;
	u32 cfi = 0, cfi_mask = 0;
	u32 prio = 0, prio_mask = 0;

	u32 old_index = tab->index;

	/* Check if vlan is wanted */
	if ((rule->flow_type & FLOW_EXT) && (rule->m_ext.vlan_tci != 0xFFFF)) {
		if (!rule->m_ext.vlan_tci)
			rule->m_ext.vlan_tci = 0xFFFF;

		vlan = RQFPR_VLN;
		vlan_mask = RQFPR_VLN;

		/* Separate the fields */
		id = rule->h_ext.vlan_tci & 0xFFF;
		id_mask = rule->m_ext.vlan_tci & 0xFFF;
		cfi = (rule->h_ext.vlan_tci >> 12) & 1;
		cfi_mask = (rule->m_ext.vlan_tci >> 12) & 1;
		prio = (rule->h_ext.vlan_tci >> 13) & 0x7;
		prio_mask = (rule->m_ext.vlan_tci >> 13) & 0x7;

		if (cfi == 1 && cfi_mask == 1) {
			vlan |= RQFPR_CFI;
			vlan_mask |= RQFPR_CFI;
		} else if (cfi == 0 && cfi_mask == 1) {
			vlan_mask |= RQFPR_CFI;
		}
	}

	switch (rule->flow_type & ~FLOW_EXT) {
	case TCP_V4_FLOW:
		gfar_set_parse_bits(RQFPR_IPV4 | RQFPR_TCP | vlan,
				RQFPR_IPV4 | RQFPR_TCP | vlan_mask, tab);
		gfar_set_basic_ip(&rule->h_u.tcp_ip4_spec,
				&rule->m_u.tcp_ip4_spec, tab);
		break;
	case UDP_V4_FLOW:
		gfar_set_parse_bits(RQFPR_IPV4 | RQFPR_UDP | vlan,
				RQFPR_IPV4 | RQFPR_UDP | vlan_mask, tab);
		gfar_set_basic_ip(&rule->h_u.udp_ip4_spec,
				&rule->m_u.udp_ip4_spec, tab);
		break;
	case SCTP_V4_FLOW:
		gfar_set_parse_bits(RQFPR_IPV4 | vlan, RQFPR_IPV4 | vlan_mask,
				tab);
		gfar_set_attribute(132, 0, RQFCR_PID_L4P, tab);
		gfar_set_basic_ip((struct ethtool_tcpip4_spec *) &rule->h_u,
				(struct ethtool_tcpip4_spec *) &rule->m_u, tab);
		break;
	case IP_USER_FLOW:
		gfar_set_parse_bits(RQFPR_IPV4 | vlan, RQFPR_IPV4 | vlan_mask,
				tab);
		gfar_set_user_ip((struct ethtool_usrip4_spec *) &rule->h_u,
				(struct ethtool_usrip4_spec *) &rule->m_u, tab);
		break;
	case ETHER_FLOW:
		if (vlan)
			gfar_set_parse_bits(vlan, vlan_mask, tab);
		gfar_set_ether((struct ethhdr *) &rule->h_u,
				(struct ethhdr *) &rule->m_u, tab);
		break;
	default:
		return -1;
	}

	/* Set the vlan attributes in the end */
	if (vlan) {
		gfar_set_attribute(id, id_mask, RQFCR_PID_VID, tab);
		gfar_set_attribute(prio, prio_mask, RQFCR_PID_PRI, tab);
	}

	/* If there has been nothing written till now, it must be a default */
	if (tab->index == old_index) {
		gfar_set_mask(0xFFFFFFFF, tab);
		tab->fe[tab->index].ctrl = 0x20;
		tab->fe[tab->index].prop = 0x0;
		tab->index++;
	}

	/* Remove last AND */
	tab->fe[tab->index - 1].ctrl &= (~RQFCR_AND);

	/* Specify which queue to use or to drop */
	if (rule->ring_cookie == RX_CLS_FLOW_DISC)
		tab->fe[tab->index - 1].ctrl |= RQFCR_RJE;
	else
		tab->fe[tab->index - 1].ctrl |= (rule->ring_cookie << 10);

	/* Only big enough entries can be clustered */
	if (tab->index > (old_index + 2)) {
		tab->fe[old_index + 1].ctrl |= RQFCR_CLE;
		tab->fe[tab->index - 1].ctrl |= RQFCR_CLE;
	}

	/* In rare cases the cache can be full while there is free space in hw */
	if (tab->index > MAX_FILER_CACHE_IDX - 1)
		return -EBUSY;

	return 0;
}

/* Copy size filer entries */
static void gfar_copy_filer_entries(struct gfar_filer_entry dst[0],
		struct gfar_filer_entry src[0], s32 size)
{
	while (size > 0) {
		size--;
		dst[size].ctrl = src[size].ctrl;
		dst[size].prop = src[size].prop;
	}
}

/* Delete the contents of the filer-table between start and end
 * and collapse them */
static int gfar_trim_filer_entries(u32 begin, u32 end, struct filer_table *tab)
{
	int length;
	if (end > MAX_FILER_CACHE_IDX || end < begin)
		return -EINVAL;

	end++;
	length = end - begin;

	/* Copy */
	while (end < tab->index) {
		tab->fe[begin].ctrl = tab->fe[end].ctrl;
		tab->fe[begin++].prop = tab->fe[end++].prop;

	}
	/* Fill up with don't cares */
	while (begin < tab->index) {
		tab->fe[begin].ctrl = 0x60;
		tab->fe[begin].prop = 0xFFFFFFFF;
		begin++;
	}

	tab->index -= length;
	return 0;
}

/* Make space on the wanted location */
static int gfar_expand_filer_entries(u32 begin, u32 length,
		struct filer_table *tab)
{
	if (length == 0 || length + tab->index > MAX_FILER_CACHE_IDX || begin
			> MAX_FILER_CACHE_IDX)
		return -EINVAL;

	gfar_copy_filer_entries(&(tab->fe[begin + length]), &(tab->fe[begin]),
			tab->index - length + 1);

	tab->index += length;
	return 0;
}

static int gfar_get_next_cluster_start(int start, struct filer_table *tab)
{
	for (; (start < tab->index) && (start < MAX_FILER_CACHE_IDX - 1); start++) {
		if ((tab->fe[start].ctrl & (RQFCR_AND | RQFCR_CLE))
				== (RQFCR_AND | RQFCR_CLE))
			return start;
	}
	return -1;
}

static int gfar_get_next_cluster_end(int start, struct filer_table *tab)
{
	for (; (start < tab->index) && (start < MAX_FILER_CACHE_IDX - 1); start++) {
		if ((tab->fe[start].ctrl & (RQFCR_AND | RQFCR_CLE))
				== (RQFCR_CLE))
			return start;
	}
	return -1;
}

/*
 * Uses hardwares clustering option to reduce
 * the number of filer table entries
 */
static void gfar_cluster_filer(struct filer_table *tab)
{
	s32 i = -1, j, iend, jend;

	while ((i = gfar_get_next_cluster_start(++i, tab)) != -1) {
		j = i;
		while ((j = gfar_get_next_cluster_start(++j, tab)) != -1) {
			/*
			 * The cluster entries self and the previous one
			 * (a mask) must be identical!
			 */
			if (tab->fe[i].ctrl != tab->fe[j].ctrl)
				break;
			if (tab->fe[i].prop != tab->fe[j].prop)
				break;
			if (tab->fe[i - 1].ctrl != tab->fe[j - 1].ctrl)
				break;
			if (tab->fe[i - 1].prop != tab->fe[j - 1].prop)
				break;
			iend = gfar_get_next_cluster_end(i, tab);
			jend = gfar_get_next_cluster_end(j, tab);
			if (jend == -1 || iend == -1)
				break;
			/*
			 * First we make some free space, where our cluster
			 * element should be. Then we copy it there and finally
			 * delete in from its old location.
			 */

			if (gfar_expand_filer_entries(iend, (jend - j), tab)
					== -EINVAL)
				break;

			gfar_copy_filer_entries(&(tab->fe[iend + 1]),
					&(tab->fe[jend + 1]), jend - j);

			if (gfar_trim_filer_entries(jend - 1,
					jend + (jend - j), tab) == -EINVAL)
				return;

			/* Mask out cluster bit */
			tab->fe[iend].ctrl &= ~(RQFCR_CLE);
		}
	}
}

/* Swaps the 0xFF80 masked bits of a1<>a2 and b1<>b2 */
static void gfar_swap_ff80_bits(struct gfar_filer_entry *a1,
		struct gfar_filer_entry *a2, struct gfar_filer_entry *b1,
		struct gfar_filer_entry *b2)
{
	u32 temp[4];
	temp[0] = a1->ctrl & 0xFF80;
	temp[1] = a2->ctrl & 0xFF80;
	temp[2] = b1->ctrl & 0xFF80;
	temp[3] = b2->ctrl & 0xFF80;

	a1->ctrl &= ~0xFF80;
	a2->ctrl &= ~0xFF80;
	b1->ctrl &= ~0xFF80;
	b2->ctrl &= ~0xFF80;

	a1->ctrl |= temp[1];
	a2->ctrl |= temp[0];
	b1->ctrl |= temp[3];
	b2->ctrl |= temp[2];
}

/*
 * Generate a list consisting of masks values with their start and
 * end of validity and block as indicator for parts belonging
 * together (glued by ANDs) in mask_table
 */
static u32 gfar_generate_mask_table(struct gfar_mask_entry *mask_table,
		struct filer_table *tab)
{
	u32 i, and_index = 0, block_index = 1;

	for (i = 0; i < tab->index; i++) {

		/* LSByte of control = 0 sets a mask */
		if (!(tab->fe[i].ctrl & 0xF)) {
			mask_table[and_index].mask = tab->fe[i].prop;
			mask_table[and_index].start = i;
			mask_table[and_index].block = block_index;
			if (and_index >= 1)
				mask_table[and_index - 1].end = i - 1;
			and_index++;
		}
		/* cluster starts will be separated because they should
		 * hold their position */
		if (tab->fe[i].ctrl & RQFCR_CLE)
			block_index++;
		/* A not set AND indicates the end of a depended block */
		if (!(tab->fe[i].ctrl & RQFCR_AND))
			block_index++;

	}

	mask_table[and_index - 1].end = i - 1;

	return and_index;
}

/*
 * Sorts the entries of mask_table by the values of the masks.
 * Important: The 0xFF80 flags of the first and last entry of a
 * block must hold their position (which queue, CLusterEnable, ReJEct,
 * AND)
 */
static void gfar_sort_mask_table(struct gfar_mask_entry *mask_table,
		struct filer_table *temp_table, u32 and_index)
{
	/* Pointer to compare function (_asc or _desc) */
	int (*gfar_comp)(const void *, const void *);

	u32 i, size = 0, start = 0, prev = 1;
	u32 old_first, old_last, new_first, new_last;

	gfar_comp = &gfar_comp_desc;

	for (i = 0; i < and_index; i++) {

		if (prev != mask_table[i].block) {
			old_first = mask_table[start].start + 1;
			old_last = mask_table[i - 1].end;
			sort(mask_table + start, size,
					sizeof(struct gfar_mask_entry),
					gfar_comp, &gfar_swap);

			/* Toggle order for every block. This makes the
			 * thing more efficient! */
			if (gfar_comp == gfar_comp_desc)
				gfar_comp = &gfar_comp_asc;
			else
				gfar_comp = &gfar_comp_desc;

			new_first = mask_table[start].start + 1;
			new_last = mask_table[i - 1].end;

			gfar_swap_ff80_bits(&temp_table->fe[new_first],
					&temp_table->fe[old_first],
					&temp_table->fe[new_last],
					&temp_table->fe[old_last]);

			start = i;
			size = 0;
		}
		size++;
		prev = mask_table[i].block;
	}

}

/*
 * Reduces the number of masks needed in the filer table to save entries
 * This is done by sorting the masks of a depended block. A depended block is
 * identified by gluing ANDs or CLE. The sorting order toggles after every
 * block. Of course entries in scope of a mask must change their location with
 * it.
 */
static int gfar_optimize_filer_masks(struct filer_table *tab)
{
	struct filer_table *temp_table;
	struct gfar_mask_entry *mask_table;

	u32 and_index = 0, previous_mask = 0, i = 0, j = 0, size = 0;
	s32 ret = 0;

	/* We need a copy of the filer table because
	 * we want to change its order */
	temp_table = kmalloc(sizeof(*temp_table), GFP_KERNEL);
	if (temp_table == NULL)
		return -ENOMEM;
	memcpy(temp_table, tab, sizeof(*temp_table));

	mask_table = kcalloc(MAX_FILER_CACHE_IDX / 2 + 1,
			sizeof(struct gfar_mask_entry), GFP_KERNEL);

	if (mask_table == NULL) {
		ret = -ENOMEM;
		goto end;
	}

	and_index = gfar_generate_mask_table(mask_table, tab);

	gfar_sort_mask_table(mask_table, temp_table, and_index);

	/* Now we can copy the data from our duplicated filer table to
	 * the real one in the order the mask table says */
	for (i = 0; i < and_index; i++) {
		size = mask_table[i].end - mask_table[i].start + 1;
		gfar_copy_filer_entries(&(tab->fe[j]),
				&(temp_table->fe[mask_table[i].start]), size);
		j += size;
	}

	/* And finally we just have to check for duplicated masks and drop the
	 * second ones */
	for (i = 0; i < tab->index && i < MAX_FILER_CACHE_IDX; i++) {
		if (tab->fe[i].ctrl == 0x80) {
			previous_mask = i++;
			break;
		}
	}
	for (; i < tab->index && i < MAX_FILER_CACHE_IDX; i++) {
		if (tab->fe[i].ctrl == 0x80) {
			if (tab->fe[i].prop == tab->fe[previous_mask].prop) {
				/* Two identical ones found!
				 * So drop the second one! */
				gfar_trim_filer_entries(i, i, tab);
			} else
				/* Not identical! */
				previous_mask = i;
		}
	}

	kfree(mask_table);
end:	kfree(temp_table);
	return ret;
}

/* Write the bit-pattern from software's buffer to hardware registers */
static int gfar_write_filer_table(struct gfar_private *priv,
		struct filer_table *tab)
{
	u32 i = 0;
	if (tab->index > MAX_FILER_IDX - 1)
		return -EBUSY;

	/* Avoid inconsistent filer table to be processed */
	lock_rx_qs(priv);

	/* Fill regular entries */
	for (; i < MAX_FILER_IDX - 1 && (tab->fe[i].ctrl | tab->fe[i].ctrl); i++)
		gfar_write_filer(priv, i, tab->fe[i].ctrl, tab->fe[i].prop);
	/* Fill the rest with fall-troughs */
	for (; i < MAX_FILER_IDX - 1; i++)
		gfar_write_filer(priv, i, 0x60, 0xFFFFFFFF);
	/* Last entry must be default accept
	 * because that's what people expect */
	gfar_write_filer(priv, i, 0x20, 0x0);

	unlock_rx_qs(priv);

	return 0;
}

static int gfar_check_capability(struct ethtool_rx_flow_spec *flow,
		struct gfar_private *priv)
{

	if (flow->flow_type & FLOW_EXT)	{
		if (~flow->m_ext.data[0] || ~flow->m_ext.data[1])
			netdev_warn(priv->ndev,
					"User-specific data not supported!\n");
		if (~flow->m_ext.vlan_etype)
			netdev_warn(priv->ndev,
					"VLAN-etype not supported!\n");
	}
	if (flow->flow_type == IP_USER_FLOW)
		if (flow->h_u.usr_ip4_spec.ip_ver != ETH_RX_NFC_IP4)
			netdev_warn(priv->ndev,
					"IP-Version differing from IPv4 not supported!\n");

	return 0;
}

static int gfar_process_filer_changes(struct gfar_private *priv)
{
	struct ethtool_flow_spec_container *j;
	struct filer_table *tab;
	s32 i = 0;
	s32 ret = 0;

	/* So index is set to zero, too! */
	tab = kzalloc(sizeof(*tab), GFP_KERNEL);
	if (tab == NULL)
		return -ENOMEM;

	/* Now convert the existing filer data from flow_spec into
	 * filer tables binary format */
	list_for_each_entry(j, &priv->rx_list.list, list) {
		ret = gfar_convert_to_filer(&j->fs, tab);
		if (ret == -EBUSY) {
			netdev_err(priv->ndev, "Rule not added: No free space!\n");
			goto end;
		}
		if (ret == -1) {
			netdev_err(priv->ndev, "Rule not added: Unsupported Flow-type!\n");
			goto end;
		}
	}

	i = tab->index;

	/* Optimizations to save entries */
	gfar_cluster_filer(tab);
	gfar_optimize_filer_masks(tab);

	pr_debug("\n\tSummary:\n"
		"\tData on hardware: %d\n"
		"\tCompression rate: %d%%\n",
		tab->index, 100 - (100 * tab->index) / i);

	/* Write everything to hardware */
	ret = gfar_write_filer_table(priv, tab);
	if (ret == -EBUSY) {
		netdev_err(priv->ndev, "Rule not added: No free space!\n");
		goto end;
	}

end:	kfree(tab);
	return ret;
}

static void gfar_invert_masks(struct ethtool_rx_flow_spec *flow)
{
	u32 i = 0;

	for (i = 0; i < sizeof(flow->m_u); i++)
		flow->m_u.hdata[i] ^= 0xFF;

	flow->m_ext.vlan_etype ^= 0xFFFF;
	flow->m_ext.vlan_tci ^= 0xFFFF;
	flow->m_ext.data[0] ^= ~0;
	flow->m_ext.data[1] ^= ~0;
}

static int gfar_add_cls(struct gfar_private *priv,
		struct ethtool_rx_flow_spec *flow)
{
	struct ethtool_flow_spec_container *temp, *comp;
	int ret = 0;

	temp = kmalloc(sizeof(*temp), GFP_KERNEL);
	if (temp == NULL)
		return -ENOMEM;
	memcpy(&temp->fs, flow, sizeof(temp->fs));

	gfar_invert_masks(&temp->fs);
	ret = gfar_check_capability(&temp->fs, priv);
	if (ret)
		goto clean_mem;
	/* Link in the new element at the right @location */
	if (list_empty(&priv->rx_list.list)) {
		ret = gfar_check_filer_hardware(priv);
		if (ret != 0)
			goto clean_mem;
		list_add(&temp->list, &priv->rx_list.list);
		goto process;
	} else {

		list_for_each_entry(comp, &priv->rx_list.list, list) {
			if (comp->fs.location > flow->location) {
				list_add_tail(&temp->list, &comp->list);
				goto process;
			}
			if (comp->fs.location == flow->location) {
				netdev_err(priv->ndev,
						"Rule not added: ID %d not free!\n",
					flow->location);
				ret = -EBUSY;
				goto clean_mem;
			}
		}
		list_add_tail(&temp->list, &priv->rx_list.list);
	}

process:
	ret = gfar_process_filer_changes(priv);
	if (ret)
		goto clean_list;
	priv->rx_list.count++;
	return ret;

clean_list:
	list_del(&temp->list);
clean_mem:
	kfree(temp);
	return ret;
}

static int gfar_del_cls(struct gfar_private *priv, u32 loc)
{
	struct ethtool_flow_spec_container *comp;
	u32 ret = -EINVAL;

	if (list_empty(&priv->rx_list.list))
		return ret;

	list_for_each_entry(comp, &priv->rx_list.list, list) {
		if (comp->fs.location == loc) {
			list_del(&comp->list);
			kfree(comp);
			priv->rx_list.count--;
			gfar_process_filer_changes(priv);
			ret = 0;
			break;
		}
	}

	return ret;

}

static int gfar_get_cls(struct gfar_private *priv, struct ethtool_rxnfc *cmd)
{
	struct ethtool_flow_spec_container *comp;
	u32 ret = -EINVAL;

	list_for_each_entry(comp, &priv->rx_list.list, list) {
		if (comp->fs.location == cmd->fs.location) {
			memcpy(&cmd->fs, &comp->fs, sizeof(cmd->fs));
			gfar_invert_masks(&cmd->fs);
			ret = 0;
			break;
		}
	}

	return ret;
}

static int gfar_get_cls_all(struct gfar_private *priv,
		struct ethtool_rxnfc *cmd, u32 *rule_locs)
{
	struct ethtool_flow_spec_container *comp;
	u32 i = 0;

	list_for_each_entry(comp, &priv->rx_list.list, list) {
		if (i <= cmd->rule_cnt) {
			rule_locs[i] = comp->fs.location;
			i++;
		}
	}

	cmd->data = MAX_FILER_IDX;

	return 0;
}

static int gfar_set_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
{
	struct gfar_private *priv = netdev_priv(dev);
	int ret = 0;

	mutex_lock(&priv->rx_queue_access);

	switch (cmd->cmd) {
	case ETHTOOL_SRXFH:
		ret = gfar_set_hash_opts(priv, cmd);
		break;
	case ETHTOOL_SRXCLSRLINS:
		if (cmd->fs.ring_cookie != RX_CLS_FLOW_DISC &&
			cmd->fs.ring_cookie >= priv->num_rx_queues) {
			ret = -EINVAL;
			break;
		}
		ret = gfar_add_cls(priv, &cmd->fs);
		break;
	case ETHTOOL_SRXCLSRLDEL:
		ret = gfar_del_cls(priv, cmd->fs.location);
		break;
	default:
		ret = -EINVAL;
	}

	mutex_unlock(&priv->rx_queue_access);

	return ret;
}

static int gfar_get_nfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
		void *rule_locs)
{
	struct gfar_private *priv = netdev_priv(dev);
	int ret = 0;

	switch (cmd->cmd) {
	case ETHTOOL_GRXRINGS:
		cmd->data = priv->num_rx_queues;
		break;
	case ETHTOOL_GRXCLSRLCNT:
		cmd->rule_cnt = priv->rx_list.count;
		break;
	case ETHTOOL_GRXCLSRULE:
		ret = gfar_get_cls(priv, cmd);
		break;
	case ETHTOOL_GRXCLSRLALL:
		ret = gfar_get_cls_all(priv, cmd, (u32 *) rule_locs);
		break;
	default:
		ret = -EINVAL;
		break;
	}

	return ret;
}

const struct ethtool_ops gfar_ethtool_ops = {
	.get_settings = gfar_gsettings,
	.set_settings = gfar_ssettings,
	.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_sset_count = gfar_sset_count,
	.get_ethtool_stats = gfar_fill_stats,
	.get_msglevel = gfar_get_msglevel,
	.set_msglevel = gfar_set_msglevel,
#ifdef CONFIG_PM
	.get_wol = gfar_get_wol,
	.set_wol = gfar_set_wol,
#endif
	.set_rxnfc = gfar_set_nfc,
	.get_rxnfc = gfar_get_nfc,
};
