/*
 * drivers/net/gianfar_sysfs.c
 *
 * Gianfar Ethernet Driver
 * This driver is designed for the non-CPM ethernet controllers
 * on the 85xx and 83xx family of integrated processors
 * Based on 8260_io/fcc_enet.c
 *
 * Author: Andy Fleming
 * Maintainer: Kumar Gala (galak@kernel.crashing.org)
 *
 * Copyright (c) 2002-2005 Freescale Semiconductor, Inc.
 *
 * 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.
 *
 * Sysfs file creation and management
 */

#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/unistd.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/etherdevice.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
#include <linux/device.h>

#include <asm/uaccess.h>
#include <linux/module.h>
#include <linux/version.h>

#include "gianfar.h"

#define GFAR_ATTR(_name) \
static ssize_t gfar_show_##_name(struct class_device *cdev, char *buf); \
static ssize_t gfar_set_##_name(struct class_device *cdev, \
		const char *buf, size_t count); \
static CLASS_DEVICE_ATTR(_name, 0644, gfar_show_##_name, gfar_set_##_name)

#define GFAR_CREATE_FILE(_dev, _name) \
	class_device_create_file(&_dev->class_dev, &class_device_attr_##_name)

GFAR_ATTR(bd_stash);
GFAR_ATTR(rx_stash_size);
GFAR_ATTR(rx_stash_index);
GFAR_ATTR(fifo_threshold);
GFAR_ATTR(fifo_starve);
GFAR_ATTR(fifo_starve_off);

#define to_net_dev(cd) container_of(cd, struct net_device, class_dev)

static ssize_t gfar_show_bd_stash(struct class_device *cdev, char *buf)
{
	struct net_device *dev = to_net_dev(cdev);
	struct gfar_private *priv = netdev_priv(dev);

	return sprintf(buf, "%s\n", priv->bd_stash_en? "on" : "off");
}

static ssize_t gfar_set_bd_stash(struct class_device *cdev,
		const char *buf, size_t count)
{
	struct net_device *dev = to_net_dev(cdev);
	struct gfar_private *priv = netdev_priv(dev);
	int new_setting = 0;
	u32 temp;
	unsigned long flags;

	/* Find out the new setting */
	if (!strncmp("on", buf, count-1) || !strncmp("1", buf, count-1))
		new_setting = 1;
	else if (!strncmp("off", buf, count-1) || !strncmp("0", buf, count-1))
		new_setting = 0;
	else
		return count;

	spin_lock_irqsave(&priv->rxlock, flags);

	/* Set the new stashing value */
	priv->bd_stash_en = new_setting;

	temp = gfar_read(&priv->regs->attr);
	
	if (new_setting)
		temp |= ATTR_BDSTASH;
	else
		temp &= ~(ATTR_BDSTASH);

	gfar_write(&priv->regs->attr, temp);

	spin_unlock_irqrestore(&priv->rxlock, flags);

	return count;
}

static ssize_t gfar_show_rx_stash_size(struct class_device *cdev, char *buf)
{
	struct net_device *dev = to_net_dev(cdev);
	struct gfar_private *priv = netdev_priv(dev);

	return sprintf(buf, "%d\n", priv->rx_stash_size);
}

static ssize_t gfar_set_rx_stash_size(struct class_device *cdev,
		const char *buf, size_t count)
{
	struct net_device *dev = to_net_dev(cdev);
	struct gfar_private *priv = netdev_priv(dev);
	unsigned int length = simple_strtoul(buf, NULL, 0);
	u32 temp;
	unsigned long flags;

	spin_lock_irqsave(&priv->rxlock, flags);
	if (length > priv->rx_buffer_size)
		return count;

	if (length == priv->rx_stash_size)
		return count;

	priv->rx_stash_size = length;

	temp = gfar_read(&priv->regs->attreli);
	temp &= ~ATTRELI_EL_MASK;
	temp |= ATTRELI_EL(length);
	gfar_write(&priv->regs->attreli, temp);

	/* Turn stashing on/off as appropriate */
	temp = gfar_read(&priv->regs->attr);

	if (length)
		temp |= ATTR_BUFSTASH;
	else
		temp &= ~(ATTR_BUFSTASH);

	gfar_write(&priv->regs->attr, temp);

	spin_unlock_irqrestore(&priv->rxlock, flags);

	return count;
}


/* Stashing will only be enabled when rx_stash_size != 0 */
static ssize_t gfar_show_rx_stash_index(struct class_device *cdev, char *buf)
{
	struct net_device *dev = to_net_dev(cdev);
	struct gfar_private *priv = netdev_priv(dev);

	return sprintf(buf, "%d\n", priv->rx_stash_index);
}

static ssize_t gfar_set_rx_stash_index(struct class_device *cdev,
		const char *buf, size_t count)
{
	struct net_device *dev = to_net_dev(cdev);
	struct gfar_private *priv = netdev_priv(dev);
	unsigned short index = simple_strtoul(buf, NULL, 0);
	u32 temp;
	unsigned long flags;

	spin_lock_irqsave(&priv->rxlock, flags);
	if (index > priv->rx_stash_size)
		return count;

	if (index == priv->rx_stash_index)
		return count;

	priv->rx_stash_index = index;

	temp = gfar_read(&priv->regs->attreli);
	temp &= ~ATTRELI_EI_MASK;
	temp |= ATTRELI_EI(index);
	gfar_write(&priv->regs->attreli, flags);

	spin_unlock_irqrestore(&priv->rxlock, flags);

	return count;
}

static ssize_t gfar_show_fifo_threshold(struct class_device *cdev, char *buf)
{
	struct net_device *dev = to_net_dev(cdev);
	struct gfar_private *priv = netdev_priv(dev);

	return sprintf(buf, "%d\n", priv->fifo_threshold);
}

static ssize_t gfar_set_fifo_threshold(struct class_device *cdev,
		const char *buf, size_t count)
{
	struct net_device *dev = to_net_dev(cdev);
	struct gfar_private *priv = netdev_priv(dev);
	unsigned int length = simple_strtoul(buf, NULL, 0);
	u32 temp;
	unsigned long flags;

	if (length > GFAR_MAX_FIFO_THRESHOLD)
		return count;

	spin_lock_irqsave(&priv->txlock, flags);

	priv->fifo_threshold = length;

	temp = gfar_read(&priv->regs->fifo_tx_thr);
	temp &= ~FIFO_TX_THR_MASK;
	temp |= length;
	gfar_write(&priv->regs->fifo_tx_thr, temp);

	spin_unlock_irqrestore(&priv->txlock, flags);

	return count;
}

static ssize_t gfar_show_fifo_starve(struct class_device *cdev, char *buf)
{
	struct net_device *dev = to_net_dev(cdev);
	struct gfar_private *priv = netdev_priv(dev);

	return sprintf(buf, "%d\n", priv->fifo_starve);
}


static ssize_t gfar_set_fifo_starve(struct class_device *cdev,
		const char *buf, size_t count)
{
	struct net_device *dev = to_net_dev(cdev);
	struct gfar_private *priv = netdev_priv(dev);
	unsigned int num = simple_strtoul(buf, NULL, 0);
	u32 temp;
	unsigned long flags;

	if (num > GFAR_MAX_FIFO_STARVE)
		return count;

	spin_lock_irqsave(&priv->txlock, flags);

	priv->fifo_starve = num;

	temp = gfar_read(&priv->regs->fifo_tx_starve);
	temp &= ~FIFO_TX_STARVE_MASK;
	temp |= num;
	gfar_write(&priv->regs->fifo_tx_starve, temp);

	spin_unlock_irqrestore(&priv->txlock, flags);

	return count;
}

static ssize_t gfar_show_fifo_starve_off(struct class_device *cdev, char *buf)
{
	struct net_device *dev = to_net_dev(cdev);
	struct gfar_private *priv = netdev_priv(dev);

	return sprintf(buf, "%d\n", priv->fifo_starve_off);
}

static ssize_t gfar_set_fifo_starve_off(struct class_device *cdev,
		const char *buf, size_t count)
{
	struct net_device *dev = to_net_dev(cdev);
	struct gfar_private *priv = netdev_priv(dev);
	unsigned int num = simple_strtoul(buf, NULL, 0);
	u32 temp;
	unsigned long flags;

	if (num > GFAR_MAX_FIFO_STARVE_OFF)
		return count;

	spin_lock_irqsave(&priv->txlock, flags);

	priv->fifo_starve_off = num;

	temp = gfar_read(&priv->regs->fifo_tx_starve_shutoff);
	temp &= ~FIFO_TX_STARVE_OFF_MASK;
	temp |= num;
	gfar_write(&priv->regs->fifo_tx_starve_shutoff, temp);

	spin_unlock_irqrestore(&priv->txlock, flags);

	return count;
}

void gfar_init_sysfs(struct net_device *dev)
{
	struct gfar_private *priv = netdev_priv(dev);

	/* Initialize the default values */
	priv->rx_stash_size = DEFAULT_STASH_LENGTH;
	priv->rx_stash_index = DEFAULT_STASH_INDEX;
	priv->fifo_threshold = DEFAULT_FIFO_TX_THR;
	priv->fifo_starve = DEFAULT_FIFO_TX_STARVE;
	priv->fifo_starve_off = DEFAULT_FIFO_TX_STARVE_OFF;
	priv->bd_stash_en = DEFAULT_BD_STASH;

	/* Create our sysfs files */
	GFAR_CREATE_FILE(dev, bd_stash);
	GFAR_CREATE_FILE(dev, rx_stash_size);
	GFAR_CREATE_FILE(dev, rx_stash_index);
	GFAR_CREATE_FILE(dev, fifo_threshold);
	GFAR_CREATE_FILE(dev, fifo_starve);
	GFAR_CREATE_FILE(dev, fifo_starve_off);

}
