2005-11-11 21:38:59 +03:00
/*
* drivers / net / gianfar_sysfs . c
*
* Gianfar Ethernet Driver
* This driver is designed for the non - CPM ethernet controllers
* on the 85 xx and 83 xx family of integrated processors
* Based on 8260 _io / fcc_enet . c
*
* Author : Andy Fleming
2006-01-11 04:00:10 +03:00
* Maintainer : Kumar Gala ( galak @ kernel . crashing . org )
2005-11-11 21:38:59 +03:00
*
* 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/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) \
2007-02-13 08:40:06 +03:00
static ssize_t gfar_show_ # # _name ( struct device * dev , \
struct device_attribute * attr , char * buf ) ; \
static ssize_t gfar_set_ # # _name ( struct device * dev , \
struct device_attribute * attr , \
2005-11-11 21:38:59 +03:00
const char * buf , size_t count ) ; \
2007-02-13 08:40:06 +03:00
static DEVICE_ATTR ( _name , 0644 , gfar_show_ # # _name , gfar_set_ # # _name )
2005-11-11 21:38:59 +03:00
# define GFAR_CREATE_FILE(_dev, _name) \
2007-02-13 08:40:06 +03:00
device_create_file ( & _dev - > dev , & dev_attr_ # # _name )
2005-11-11 21:38:59 +03:00
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 ) ;
2007-02-13 08:40:06 +03:00
static ssize_t gfar_show_bd_stash ( struct device * dev ,
struct device_attribute * attr , char * buf )
2005-11-11 21:38:59 +03:00
{
2007-02-13 08:40:06 +03:00
struct gfar_private * priv = netdev_priv ( to_net_dev ( dev ) ) ;
2005-11-11 21:38:59 +03:00
2007-02-13 08:40:06 +03:00
return sprintf ( buf , " %s \n " , priv - > bd_stash_en ? " on " : " off " ) ;
2005-11-11 21:38:59 +03:00
}
2007-02-13 08:40:06 +03:00
static ssize_t gfar_set_bd_stash ( struct device * dev ,
struct device_attribute * attr ,
const char * buf , size_t count )
2005-11-11 21:38:59 +03:00
{
2007-02-13 08:40:06 +03:00
struct gfar_private * priv = netdev_priv ( to_net_dev ( dev ) ) ;
2005-11-11 21:38:59 +03:00
int new_setting = 0 ;
u32 temp ;
unsigned long flags ;
/* Find out the new setting */
2007-02-13 08:40:06 +03:00
if ( ! strncmp ( " on " , buf , count - 1 ) | | ! strncmp ( " 1 " , buf , count - 1 ) )
2005-11-11 21:38:59 +03:00
new_setting = 1 ;
2007-02-13 08:40:06 +03:00
else if ( ! strncmp ( " off " , buf , count - 1 )
| | ! strncmp ( " 0 " , buf , count - 1 ) )
2005-11-11 21:38:59 +03:00
new_setting = 0 ;
else
return count ;
2006-04-21 01:44:29 +04:00
spin_lock_irqsave ( & priv - > rxlock , flags ) ;
2005-11-11 21:38:59 +03:00
/* Set the new stashing value */
priv - > bd_stash_en = new_setting ;
temp = gfar_read ( & priv - > regs - > attr ) ;
2006-09-13 21:24:59 +04:00
2005-11-11 21:38:59 +03:00
if ( new_setting )
temp | = ATTR_BDSTASH ;
else
temp & = ~ ( ATTR_BDSTASH ) ;
gfar_write ( & priv - > regs - > attr , temp ) ;
2006-04-21 01:44:29 +04:00
spin_unlock_irqrestore ( & priv - > rxlock , flags ) ;
2005-11-11 21:38:59 +03:00
return count ;
}
2007-02-13 08:40:06 +03:00
static ssize_t gfar_show_rx_stash_size ( struct device * dev ,
struct device_attribute * attr , char * buf )
2005-11-11 21:38:59 +03:00
{
2007-02-13 08:40:06 +03:00
struct gfar_private * priv = netdev_priv ( to_net_dev ( dev ) ) ;
2005-11-11 21:38:59 +03:00
return sprintf ( buf , " %d \n " , priv - > rx_stash_size ) ;
}
2007-02-13 08:40:06 +03:00
static ssize_t gfar_set_rx_stash_size ( struct device * dev ,
struct device_attribute * attr ,
const char * buf , size_t count )
2005-11-11 21:38:59 +03:00
{
2007-02-13 08:40:06 +03:00
struct gfar_private * priv = netdev_priv ( to_net_dev ( dev ) ) ;
2005-11-11 21:38:59 +03:00
unsigned int length = simple_strtoul ( buf , NULL , 0 ) ;
u32 temp ;
unsigned long flags ;
2006-04-21 01:44:29 +04:00
spin_lock_irqsave ( & priv - > rxlock , flags ) ;
2005-11-11 21:38:59 +03:00
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 ) ;
2006-04-21 01:44:29 +04:00
spin_unlock_irqrestore ( & priv - > rxlock , flags ) ;
2005-11-11 21:38:59 +03:00
return count ;
}
/* Stashing will only be enabled when rx_stash_size != 0 */
2007-02-13 08:40:06 +03:00
static ssize_t gfar_show_rx_stash_index ( struct device * dev ,
struct device_attribute * attr ,
char * buf )
2005-11-11 21:38:59 +03:00
{
2007-02-13 08:40:06 +03:00
struct gfar_private * priv = netdev_priv ( to_net_dev ( dev ) ) ;
2005-11-11 21:38:59 +03:00
return sprintf ( buf , " %d \n " , priv - > rx_stash_index ) ;
}
2007-02-13 08:40:06 +03:00
static ssize_t gfar_set_rx_stash_index ( struct device * dev ,
struct device_attribute * attr ,
const char * buf , size_t count )
2005-11-11 21:38:59 +03:00
{
2007-02-13 08:40:06 +03:00
struct gfar_private * priv = netdev_priv ( to_net_dev ( dev ) ) ;
2005-11-11 21:38:59 +03:00
unsigned short index = simple_strtoul ( buf , NULL , 0 ) ;
u32 temp ;
unsigned long flags ;
2006-04-21 01:44:29 +04:00
spin_lock_irqsave ( & priv - > rxlock , flags ) ;
2005-11-11 21:38:59 +03:00
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 ) ;
2006-04-21 01:44:29 +04:00
spin_unlock_irqrestore ( & priv - > rxlock , flags ) ;
2005-11-11 21:38:59 +03:00
return count ;
}
2007-02-13 08:40:06 +03:00
static ssize_t gfar_show_fifo_threshold ( struct device * dev ,
struct device_attribute * attr ,
char * buf )
2005-11-11 21:38:59 +03:00
{
2007-02-13 08:40:06 +03:00
struct gfar_private * priv = netdev_priv ( to_net_dev ( dev ) ) ;
2005-11-11 21:38:59 +03:00
return sprintf ( buf , " %d \n " , priv - > fifo_threshold ) ;
}
2007-02-13 08:40:06 +03:00
static ssize_t gfar_set_fifo_threshold ( struct device * dev ,
struct device_attribute * attr ,
const char * buf , size_t count )
2005-11-11 21:38:59 +03:00
{
2007-02-13 08:40:06 +03:00
struct gfar_private * priv = netdev_priv ( to_net_dev ( dev ) ) ;
2005-11-11 21:38:59 +03:00
unsigned int length = simple_strtoul ( buf , NULL , 0 ) ;
u32 temp ;
unsigned long flags ;
if ( length > GFAR_MAX_FIFO_THRESHOLD )
return count ;
2006-04-21 01:44:29 +04:00
spin_lock_irqsave ( & priv - > txlock , flags ) ;
2005-11-11 21:38:59 +03:00
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 ) ;
2006-04-21 01:44:29 +04:00
spin_unlock_irqrestore ( & priv - > txlock , flags ) ;
2005-11-11 21:38:59 +03:00
return count ;
}
2007-02-13 08:40:06 +03:00
static ssize_t gfar_show_fifo_starve ( struct device * dev ,
struct device_attribute * attr , char * buf )
2005-11-11 21:38:59 +03:00
{
2007-02-13 08:40:06 +03:00
struct gfar_private * priv = netdev_priv ( to_net_dev ( dev ) ) ;
2005-11-11 21:38:59 +03:00
return sprintf ( buf , " %d \n " , priv - > fifo_starve ) ;
}
2007-02-13 08:40:06 +03:00
static ssize_t gfar_set_fifo_starve ( struct device * dev ,
struct device_attribute * attr ,
const char * buf , size_t count )
2005-11-11 21:38:59 +03:00
{
2007-02-13 08:40:06 +03:00
struct gfar_private * priv = netdev_priv ( to_net_dev ( dev ) ) ;
2005-11-11 21:38:59 +03:00
unsigned int num = simple_strtoul ( buf , NULL , 0 ) ;
u32 temp ;
unsigned long flags ;
if ( num > GFAR_MAX_FIFO_STARVE )
return count ;
2006-04-21 01:44:29 +04:00
spin_lock_irqsave ( & priv - > txlock , flags ) ;
2005-11-11 21:38:59 +03:00
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 ) ;
2006-04-21 01:44:29 +04:00
spin_unlock_irqrestore ( & priv - > txlock , flags ) ;
2005-11-11 21:38:59 +03:00
return count ;
}
2007-02-13 08:40:06 +03:00
static ssize_t gfar_show_fifo_starve_off ( struct device * dev ,
struct device_attribute * attr ,
char * buf )
2005-11-11 21:38:59 +03:00
{
2007-02-13 08:40:06 +03:00
struct gfar_private * priv = netdev_priv ( to_net_dev ( dev ) ) ;
2005-11-11 21:38:59 +03:00
return sprintf ( buf , " %d \n " , priv - > fifo_starve_off ) ;
}
2007-02-13 08:40:06 +03:00
static ssize_t gfar_set_fifo_starve_off ( struct device * dev ,
struct device_attribute * attr ,
const char * buf , size_t count )
2005-11-11 21:38:59 +03:00
{
2007-02-13 08:40:06 +03:00
struct gfar_private * priv = netdev_priv ( to_net_dev ( dev ) ) ;
2005-11-11 21:38:59 +03:00
unsigned int num = simple_strtoul ( buf , NULL , 0 ) ;
u32 temp ;
unsigned long flags ;
if ( num > GFAR_MAX_FIFO_STARVE_OFF )
return count ;
2006-04-21 01:44:29 +04:00
spin_lock_irqsave ( & priv - > txlock , flags ) ;
2005-11-11 21:38:59 +03:00
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 ) ;
2006-04-21 01:44:29 +04:00
spin_unlock_irqrestore ( & priv - > txlock , flags ) ;
2005-11-11 21:38:59 +03:00
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 ) ;
}