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 )
2009-11-02 10:03:00 +03:00
* Modifier : Sandeep Gopalpet < sandeep . kumar @ freescale . com >
2005-11-11 21:38:59 +03:00
*
2009-11-02 10:03:00 +03:00
* Copyright 2002 - 2009 Freescale Semiconductor , Inc .
2005-11-11 21:38:59 +03:00
*
* 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/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 "gianfar.h"
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 ) ) ;
2009-11-02 10:03:34 +03:00
struct gfar __iomem * regs = priv - > gfargrp [ 0 ] . regs ;
2005-11-11 21:38:59 +03:00
int new_setting = 0 ;
u32 temp ;
unsigned long flags ;
2009-02-05 03:43:44 +03:00
if ( ! ( priv - > device_flags & FSL_GIANFAR_DEV_HAS_BD_STASHING ) )
return count ;
2009-11-02 10:03:00 +03:00
2005-11-11 21:38:59 +03:00
/* 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 ;
2009-12-03 10:58:21 +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 ;
2009-11-02 10:03:15 +03:00
local_irq_save ( flags ) ;
lock_rx_qs ( priv ) ;
2005-11-11 21:38:59 +03:00
/* Set the new stashing value */
priv - > bd_stash_en = new_setting ;
2009-11-02 10:03:09 +03:00
temp = gfar_read ( & 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 ) ;
2009-11-02 10:03:09 +03:00
gfar_write ( & regs - > attr , temp ) ;
2005-11-11 21:38:59 +03:00
2009-11-02 10:03:15 +03:00
unlock_rx_qs ( priv ) ;
local_irq_restore ( flags ) ;
2005-11-11 21:38:59 +03:00
return count ;
}
2009-02-01 11:54:16 +03:00
static DEVICE_ATTR ( bd_stash , 0644 , gfar_show_bd_stash , gfar_set_bd_stash ) ;
2007-12-02 08:12:45 +03:00
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 ) ) ;
2009-11-02 10:03:34 +03:00
struct gfar __iomem * regs = priv - > gfargrp [ 0 ] . regs ;
2005-11-11 21:38:59 +03:00
unsigned int length = simple_strtoul ( buf , NULL , 0 ) ;
u32 temp ;
unsigned long flags ;
2009-02-05 03:43:44 +03:00
if ( ! ( priv - > device_flags & FSL_GIANFAR_DEV_HAS_BUF_STASHING ) )
return count ;
2009-11-02 10:03:15 +03:00
local_irq_save ( flags ) ;
lock_rx_qs ( priv ) ;
2009-11-02 10:03:00 +03:00
2005-11-11 21:38:59 +03:00
if ( length > priv - > rx_buffer_size )
2008-05-02 22:00:30 +04:00
goto out ;
2005-11-11 21:38:59 +03:00
if ( length = = priv - > rx_stash_size )
2008-05-02 22:00:30 +04:00
goto out ;
2005-11-11 21:38:59 +03:00
priv - > rx_stash_size = length ;
2009-11-02 10:03:09 +03:00
temp = gfar_read ( & regs - > attreli ) ;
2005-11-11 21:38:59 +03:00
temp & = ~ ATTRELI_EL_MASK ;
temp | = ATTRELI_EL ( length ) ;
2009-11-02 10:03:09 +03:00
gfar_write ( & regs - > attreli , temp ) ;
2005-11-11 21:38:59 +03:00
/* Turn stashing on/off as appropriate */
2009-11-02 10:03:09 +03:00
temp = gfar_read ( & regs - > attr ) ;
2005-11-11 21:38:59 +03:00
if ( length )
temp | = ATTR_BUFSTASH ;
else
temp & = ~ ( ATTR_BUFSTASH ) ;
2009-11-02 10:03:09 +03:00
gfar_write ( & regs - > attr , temp ) ;
2005-11-11 21:38:59 +03:00
2008-05-02 22:00:30 +04:00
out :
2009-11-02 10:03:15 +03:00
unlock_rx_qs ( priv ) ;
local_irq_restore ( flags ) ;
2005-11-11 21:38:59 +03:00
return count ;
}
2009-02-01 11:54:16 +03:00
static DEVICE_ATTR ( rx_stash_size , 0644 , gfar_show_rx_stash_size ,
gfar_set_rx_stash_size ) ;
2007-12-02 08:12:45 +03:00
2005-11-11 21:38:59 +03:00
/* 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 ) ) ;
2009-11-02 10:03:34 +03:00
struct gfar __iomem * regs = priv - > gfargrp [ 0 ] . regs ;
2005-11-11 21:38:59 +03:00
unsigned short index = simple_strtoul ( buf , NULL , 0 ) ;
u32 temp ;
unsigned long flags ;
2009-02-05 03:43:44 +03:00
if ( ! ( priv - > device_flags & FSL_GIANFAR_DEV_HAS_BUF_STASHING ) )
return count ;
2009-11-02 10:03:15 +03:00
local_irq_save ( flags ) ;
lock_rx_qs ( priv ) ;
2009-11-02 10:03:00 +03:00
2005-11-11 21:38:59 +03:00
if ( index > priv - > rx_stash_size )
2008-05-02 22:00:30 +04:00
goto out ;
2005-11-11 21:38:59 +03:00
if ( index = = priv - > rx_stash_index )
2008-05-02 22:00:30 +04:00
goto out ;
2005-11-11 21:38:59 +03:00
priv - > rx_stash_index = index ;
2009-11-02 10:03:09 +03:00
temp = gfar_read ( & regs - > attreli ) ;
2005-11-11 21:38:59 +03:00
temp & = ~ ATTRELI_EI_MASK ;
temp | = ATTRELI_EI ( index ) ;
2009-11-10 17:11:07 +03:00
gfar_write ( & regs - > attreli , temp ) ;
2005-11-11 21:38:59 +03:00
2008-05-02 22:00:30 +04:00
out :
2009-11-02 10:03:15 +03:00
unlock_rx_qs ( priv ) ;
local_irq_restore ( flags ) ;
2005-11-11 21:38:59 +03:00
return count ;
}
2009-02-01 11:54:16 +03:00
static DEVICE_ATTR ( rx_stash_index , 0644 , gfar_show_rx_stash_index ,
gfar_set_rx_stash_index ) ;
2007-12-02 08:12:45 +03:00
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 ) ) ;
2009-11-02 10:03:34 +03:00
struct gfar __iomem * regs = priv - > gfargrp [ 0 ] . regs ;
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 ;
2009-11-02 10:03:15 +03:00
local_irq_save ( flags ) ;
lock_tx_qs ( priv ) ;
2005-11-11 21:38:59 +03:00
priv - > fifo_threshold = length ;
2009-11-02 10:03:09 +03:00
temp = gfar_read ( & regs - > fifo_tx_thr ) ;
2005-11-11 21:38:59 +03:00
temp & = ~ FIFO_TX_THR_MASK ;
temp | = length ;
2009-11-02 10:03:09 +03:00
gfar_write ( & regs - > fifo_tx_thr , temp ) ;
2005-11-11 21:38:59 +03:00
2009-11-02 10:03:15 +03:00
unlock_tx_qs ( priv ) ;
local_irq_restore ( flags ) ;
2005-11-11 21:38:59 +03:00
return count ;
}
2009-02-01 11:54:16 +03:00
static DEVICE_ATTR ( fifo_threshold , 0644 , gfar_show_fifo_threshold ,
gfar_set_fifo_threshold ) ;
2007-12-02 08:12:45 +03:00
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 ) ) ;
2009-11-02 10:03:34 +03:00
struct gfar __iomem * regs = priv - > gfargrp [ 0 ] . regs ;
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 ;
2009-11-02 10:03:15 +03:00
local_irq_save ( flags ) ;
lock_tx_qs ( priv ) ;
2005-11-11 21:38:59 +03:00
priv - > fifo_starve = num ;
2009-11-02 10:03:09 +03:00
temp = gfar_read ( & regs - > fifo_tx_starve ) ;
2005-11-11 21:38:59 +03:00
temp & = ~ FIFO_TX_STARVE_MASK ;
temp | = num ;
2009-11-02 10:03:09 +03:00
gfar_write ( & regs - > fifo_tx_starve , temp ) ;
2005-11-11 21:38:59 +03:00
2009-11-02 10:03:15 +03:00
unlock_tx_qs ( priv ) ;
local_irq_restore ( flags ) ;
2005-11-11 21:38:59 +03:00
return count ;
}
2009-02-01 11:54:16 +03:00
static DEVICE_ATTR ( fifo_starve , 0644 , gfar_show_fifo_starve ,
gfar_set_fifo_starve ) ;
2007-12-02 08:12:45 +03:00
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 ) ) ;
2009-11-02 10:03:34 +03:00
struct gfar __iomem * regs = priv - > gfargrp [ 0 ] . regs ;
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 ;
2009-11-02 10:03:15 +03:00
local_irq_save ( flags ) ;
lock_tx_qs ( priv ) ;
2005-11-11 21:38:59 +03:00
priv - > fifo_starve_off = num ;
2009-11-02 10:03:09 +03:00
temp = gfar_read ( & regs - > fifo_tx_starve_shutoff ) ;
2005-11-11 21:38:59 +03:00
temp & = ~ FIFO_TX_STARVE_OFF_MASK ;
temp | = num ;
2009-11-02 10:03:09 +03:00
gfar_write ( & regs - > fifo_tx_starve_shutoff , temp ) ;
2005-11-11 21:38:59 +03:00
2009-11-02 10:03:15 +03:00
unlock_tx_qs ( priv ) ;
local_irq_restore ( flags ) ;
2005-11-11 21:38:59 +03:00
return count ;
}
2009-02-01 11:54:16 +03:00
static DEVICE_ATTR ( fifo_starve_off , 0644 , gfar_show_fifo_starve_off ,
gfar_set_fifo_starve_off ) ;
2007-12-02 08:12:45 +03:00
2005-11-11 21:38:59 +03:00
void gfar_init_sysfs ( struct net_device * dev )
{
struct gfar_private * priv = netdev_priv ( dev ) ;
2007-12-02 08:12:45 +03:00
int rc ;
2005-11-11 21:38:59 +03:00
/* Initialize the default values */
priv - > fifo_threshold = DEFAULT_FIFO_TX_THR ;
priv - > fifo_starve = DEFAULT_FIFO_TX_STARVE ;
priv - > fifo_starve_off = DEFAULT_FIFO_TX_STARVE_OFF ;
/* Create our sysfs files */
2007-12-02 08:12:45 +03:00
rc = device_create_file ( & dev - > dev , & dev_attr_bd_stash ) ;
rc | = device_create_file ( & dev - > dev , & dev_attr_rx_stash_size ) ;
rc | = device_create_file ( & dev - > dev , & dev_attr_rx_stash_index ) ;
rc | = device_create_file ( & dev - > dev , & dev_attr_fifo_threshold ) ;
rc | = device_create_file ( & dev - > dev , & dev_attr_fifo_starve ) ;
rc | = device_create_file ( & dev - > dev , & dev_attr_fifo_starve_off ) ;
if ( rc )
dev_err ( & dev - > dev , " Error creating gianfar sysfs files. \n " ) ;
2005-11-11 21:38:59 +03:00
}