2006-09-13 19:44:31 +04:00
/*
* linux / drivers / net / ehea / ehea_ethtool . c
*
* eHEA ethernet device driver for IBM eServer System p
*
* ( C ) Copyright IBM Corp . 2006
*
* Authors :
* Christoph Raisch < raisch @ de . ibm . com >
* Jan - Bernd Themann < themann @ de . ibm . com >
* Thomas Klein < tklein @ de . ibm . com >
*
*
* 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 , or ( at your option )
* any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "ehea.h"
# include "ehea_phyp.h"
static int ehea_get_settings ( struct net_device * dev , struct ethtool_cmd * cmd )
{
struct ehea_port * port = netdev_priv ( dev ) ;
int ret ;
ret = ehea_sense_port_attr ( port ) ;
if ( ret )
return ret ;
if ( netif_carrier_ok ( dev ) ) {
2008-02-01 05:20:48 +03:00
switch ( port - > port_speed ) {
2006-09-13 19:44:31 +04:00
case EHEA_SPEED_10M : cmd - > speed = SPEED_10 ; break ;
case EHEA_SPEED_100M : cmd - > speed = SPEED_100 ; break ;
case EHEA_SPEED_1G : cmd - > speed = SPEED_1000 ; break ;
case EHEA_SPEED_10G : cmd - > speed = SPEED_10000 ; break ;
}
cmd - > duplex = port - > full_duplex = = 1 ?
DUPLEX_FULL : DUPLEX_HALF ;
} else {
cmd - > speed = - 1 ;
cmd - > duplex = - 1 ;
}
cmd - > supported = ( SUPPORTED_10000baseT_Full | SUPPORTED_1000baseT_Full
| SUPPORTED_100baseT_Full | SUPPORTED_100baseT_Half
| SUPPORTED_10baseT_Full | SUPPORTED_10baseT_Half
| SUPPORTED_Autoneg | SUPPORTED_FIBRE ) ;
cmd - > advertising = ( ADVERTISED_10000baseT_Full | ADVERTISED_Autoneg
| ADVERTISED_FIBRE ) ;
cmd - > port = PORT_FIBRE ;
cmd - > autoneg = port - > autoneg = = 1 ? AUTONEG_ENABLE : AUTONEG_DISABLE ;
return 0 ;
}
static int ehea_set_settings ( struct net_device * dev , struct ethtool_cmd * cmd )
{
struct ehea_port * port = netdev_priv ( dev ) ;
int ret = 0 ;
u32 sp ;
if ( cmd - > autoneg = = AUTONEG_ENABLE ) {
sp = EHEA_SPEED_AUTONEG ;
goto doit ;
}
2008-02-01 05:20:48 +03:00
switch ( cmd - > speed ) {
2006-09-13 19:44:31 +04:00
case SPEED_10 :
if ( cmd - > duplex = = DUPLEX_FULL )
sp = H_SPEED_10M_F ;
else
sp = H_SPEED_10M_H ;
break ;
case SPEED_100 :
if ( cmd - > duplex = = DUPLEX_FULL )
sp = H_SPEED_100M_F ;
else
sp = H_SPEED_100M_H ;
break ;
case SPEED_1000 :
if ( cmd - > duplex = = DUPLEX_FULL )
sp = H_SPEED_1G_F ;
else
ret = - EINVAL ;
break ;
case SPEED_10000 :
if ( cmd - > duplex = = DUPLEX_FULL )
sp = H_SPEED_10G_F ;
else
ret = - EINVAL ;
break ;
default :
ret = - EINVAL ;
break ;
}
if ( ret )
goto out ;
doit :
ret = ehea_set_portspeed ( port , sp ) ;
if ( ! ret )
tree-wide: fix assorted typos all over the place
That is "success", "unknown", "through", "performance", "[re|un]mapping"
, "access", "default", "reasonable", "[con]currently", "temperature"
, "channel", "[un]used", "application", "example","hierarchy", "therefore"
, "[over|under]flow", "contiguous", "threshold", "enough" and others.
Signed-off-by: André Goddard Rosa <andre.goddard@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2009-11-14 18:09:05 +03:00
ehea_info ( " %s: Port speed successfully set: %dMbps "
2006-09-13 19:44:31 +04:00
" %s Duplex " ,
port - > netdev - > name , port - > port_speed ,
port - > full_duplex = = 1 ? " Full " : " Half " ) ;
out :
return ret ;
}
static int ehea_nway_reset ( struct net_device * dev )
{
struct ehea_port * port = netdev_priv ( dev ) ;
int ret ;
ret = ehea_set_portspeed ( port , EHEA_SPEED_AUTONEG ) ;
if ( ! ret )
tree-wide: fix assorted typos all over the place
That is "success", "unknown", "through", "performance", "[re|un]mapping"
, "access", "default", "reasonable", "[con]currently", "temperature"
, "channel", "[un]used", "application", "example","hierarchy", "therefore"
, "[over|under]flow", "contiguous", "threshold", "enough" and others.
Signed-off-by: André Goddard Rosa <andre.goddard@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2009-11-14 18:09:05 +03:00
ehea_info ( " %s: Port speed successfully set: %dMbps "
2006-09-13 19:44:31 +04:00
" %s Duplex " ,
port - > netdev - > name , port - > port_speed ,
port - > full_duplex = = 1 ? " Full " : " Half " ) ;
return ret ;
}
static void ehea_get_drvinfo ( struct net_device * dev ,
struct ethtool_drvinfo * info )
{
2007-03-27 09:47:22 +04:00
strlcpy ( info - > driver , DRV_NAME , sizeof ( info - > driver ) ) ;
strlcpy ( info - > version , DRV_VERSION , sizeof ( info - > version ) ) ;
2006-09-13 19:44:31 +04:00
}
static u32 ehea_get_msglevel ( struct net_device * dev )
{
struct ehea_port * port = netdev_priv ( dev ) ;
return port - > msg_enable ;
}
static void ehea_set_msglevel ( struct net_device * dev , u32 value )
{
struct ehea_port * port = netdev_priv ( dev ) ;
port - > msg_enable = value ;
}
static u32 ehea_get_rx_csum ( struct net_device * dev )
{
return 1 ;
}
static char ehea_ethtool_stats_keys [ ] [ ETH_GSTRING_LEN ] = {
{ " sig_comp_iv " } ,
{ " swqe_refill_th " } ,
{ " port resets " } ,
2007-03-23 19:18:53 +03:00
{ " Receive errors " } ,
{ " TCP cksum errors " } ,
{ " IP cksum errors " } ,
{ " Frame cksum errors " } ,
{ " num SQ stopped " } ,
{ " SQ stopped " } ,
{ " PR0 free_swqes " } ,
{ " PR1 free_swqes " } ,
{ " PR2 free_swqes " } ,
{ " PR3 free_swqes " } ,
{ " PR4 free_swqes " } ,
{ " PR5 free_swqes " } ,
{ " PR6 free_swqes " } ,
{ " PR7 free_swqes " } ,
2007-09-26 03:16:34 +04:00
{ " LRO aggregated " } ,
{ " LRO flushed " } ,
{ " LRO no_desc " } ,
2006-09-13 19:44:31 +04:00
} ;
static void ehea_get_strings ( struct net_device * dev , u32 stringset , u8 * data )
{
if ( stringset = = ETH_SS_STATS ) {
memcpy ( data , & ehea_ethtool_stats_keys ,
sizeof ( ehea_ethtool_stats_keys ) ) ;
}
}
2007-10-04 05:07:32 +04:00
static int ehea_get_sset_count ( struct net_device * dev , int sset )
2006-09-13 19:44:31 +04:00
{
2007-10-04 05:07:32 +04:00
switch ( sset ) {
case ETH_SS_STATS :
return ARRAY_SIZE ( ehea_ethtool_stats_keys ) ;
default :
return - EOPNOTSUPP ;
}
2006-09-13 19:44:31 +04:00
}
static void ehea_get_ethtool_stats ( struct net_device * dev ,
struct ethtool_stats * stats , u64 * data )
{
2007-03-23 19:18:53 +03:00
int i , k , tmp ;
2006-09-13 19:44:31 +04:00
struct ehea_port * port = netdev_priv ( dev ) ;
2007-10-04 05:07:32 +04:00
for ( i = 0 ; i < ehea_get_sset_count ( dev , ETH_SS_STATS ) ; i + + )
2006-09-13 19:44:31 +04:00
data [ i ] = 0 ;
i = 0 ;
data [ i + + ] = port - > sig_comp_iv ;
data [ i + + ] = port - > port_res [ 0 ] . swqe_refill_th ;
data [ i + + ] = port - > resets ;
2007-03-23 19:18:53 +03:00
for ( k = 0 , tmp = 0 ; k < EHEA_MAX_PORT_RES ; k + + )
tmp + = port - > port_res [ k ] . p_stats . poll_receive_errors ;
data [ i + + ] = tmp ;
for ( k = 0 , tmp = 0 ; k < EHEA_MAX_PORT_RES ; k + + )
tmp + = port - > port_res [ k ] . p_stats . err_tcp_cksum ;
data [ i + + ] = tmp ;
for ( k = 0 , tmp = 0 ; k < EHEA_MAX_PORT_RES ; k + + )
tmp + = port - > port_res [ k ] . p_stats . err_ip_cksum ;
data [ i + + ] = tmp ;
for ( k = 0 , tmp = 0 ; k < EHEA_MAX_PORT_RES ; k + + )
tmp + = port - > port_res [ k ] . p_stats . err_frame_crc ;
data [ i + + ] = tmp ;
for ( k = 0 , tmp = 0 ; k < EHEA_MAX_PORT_RES ; k + + )
tmp + = port - > port_res [ k ] . p_stats . queue_stopped ;
data [ i + + ] = tmp ;
for ( k = 0 , tmp = 0 ; k < EHEA_MAX_PORT_RES ; k + + )
tmp | = port - > port_res [ k ] . queue_stopped ;
data [ i + + ] = tmp ;
for ( k = 0 ; k < 8 ; k + + )
data [ i + + ] = atomic_read ( & port - > port_res [ k ] . swqe_avail ) ;
2006-09-13 19:44:31 +04:00
2007-09-26 03:16:34 +04:00
for ( k = 0 , tmp = 0 ; k < EHEA_MAX_PORT_RES ; k + + )
tmp | = port - > port_res [ k ] . lro_mgr . stats . aggregated ;
data [ i + + ] = tmp ;
for ( k = 0 , tmp = 0 ; k < EHEA_MAX_PORT_RES ; k + + )
tmp | = port - > port_res [ k ] . lro_mgr . stats . flushed ;
data [ i + + ] = tmp ;
for ( k = 0 , tmp = 0 ; k < EHEA_MAX_PORT_RES ; k + + )
tmp | = port - > port_res [ k ] . lro_mgr . stats . no_desc ;
data [ i + + ] = tmp ;
2006-09-13 19:44:31 +04:00
}
2006-09-13 22:30:00 +04:00
const struct ethtool_ops ehea_ethtool_ops = {
2006-09-13 19:44:31 +04:00
. get_settings = ehea_get_settings ,
. get_drvinfo = ehea_get_drvinfo ,
. get_msglevel = ehea_get_msglevel ,
. set_msglevel = ehea_set_msglevel ,
. get_link = ethtool_op_get_link ,
. set_tso = ethtool_op_set_tso ,
. get_strings = ehea_get_strings ,
2007-10-04 05:07:32 +04:00
. get_sset_count = ehea_get_sset_count ,
2006-09-13 19:44:31 +04:00
. get_ethtool_stats = ehea_get_ethtool_stats ,
. get_rx_csum = ehea_get_rx_csum ,
. set_settings = ehea_set_settings ,
. nway_reset = ehea_nway_reset , /* Restart autonegotiation */
} ;
void ehea_set_ethtool_ops ( struct net_device * netdev )
{
SET_ETHTOOL_OPS ( netdev , & ehea_ethtool_ops ) ;
}