2008-02-21 05:57:59 +03:00
/*
* Copyright ( C ) 2006 - 2008 PA Semi , Inc
*
* Ethtool hooks for the PA Semi PWRficient onchip 1 G / 10 G Ethernet MACs
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*
* 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 . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*/
# include <linux/netdevice.h>
# include <linux/ethtool.h>
# include <linux/pci.h>
# include <linux/inet_lro.h>
# include <asm/pasemi_dma.h>
# include "pasemi_mac.h"
static struct {
const char str [ ETH_GSTRING_LEN ] ;
} ethtool_stats_keys [ ] = {
{ " rx-drops " } ,
{ " rx-bytes " } ,
{ " rx-packets " } ,
{ " rx-broadcast-packets " } ,
{ " rx-multicast-packets " } ,
{ " rx-crc-errors " } ,
{ " rx-undersize-errors " } ,
{ " rx-oversize-errors " } ,
{ " rx-short-fragment-errors " } ,
{ " rx-jabber-errors " } ,
{ " rx-64-byte-packets " } ,
{ " rx-65-127-byte-packets " } ,
{ " rx-128-255-byte-packets " } ,
{ " rx-256-511-byte-packets " } ,
{ " rx-512-1023-byte-packets " } ,
{ " rx-1024-1518-byte-packets " } ,
{ " rx-pause-frames " } ,
{ " tx-bytes " } ,
{ " tx-packets " } ,
{ " tx-broadcast-packets " } ,
{ " tx-multicast-packets " } ,
{ " tx-collisions " } ,
{ " tx-late-collisions " } ,
{ " tx-excessive-collisions " } ,
{ " tx-crc-errors " } ,
{ " tx-undersize-errors " } ,
{ " tx-oversize-errors " } ,
{ " tx-64-byte-packets " } ,
{ " tx-65-127-byte-packets " } ,
{ " tx-128-255-byte-packets " } ,
{ " tx-256-511-byte-packets " } ,
{ " tx-512-1023-byte-packets " } ,
{ " tx-1024-1518-byte-packets " } ,
} ;
static int
pasemi_mac_ethtool_get_settings ( struct net_device * netdev ,
struct ethtool_cmd * cmd )
{
struct pasemi_mac * mac = netdev_priv ( netdev ) ;
struct phy_device * phydev = mac - > phydev ;
2009-10-05 07:27:56 +04:00
if ( ! phydev )
return - EOPNOTSUPP ;
2008-02-21 05:57:59 +03:00
return phy_ethtool_gset ( phydev , cmd ) ;
}
2009-10-12 15:25:05 +04:00
static int
pasemi_mac_ethtool_set_settings ( struct net_device * netdev ,
struct ethtool_cmd * cmd )
{
struct pasemi_mac * mac = netdev_priv ( netdev ) ;
struct phy_device * phydev = mac - > phydev ;
if ( ! phydev )
return - EOPNOTSUPP ;
return phy_ethtool_sset ( phydev , cmd ) ;
}
2008-02-21 05:57:59 +03:00
static void
pasemi_mac_ethtool_get_drvinfo ( struct net_device * netdev ,
struct ethtool_drvinfo * drvinfo )
{
struct pasemi_mac * mac ;
mac = netdev_priv ( netdev ) ;
/* clear and fill out info */
memset ( drvinfo , 0 , sizeof ( struct ethtool_drvinfo ) ) ;
strncpy ( drvinfo - > driver , " pasemi_mac " , 12 ) ;
strcpy ( drvinfo - > version , " N/A " ) ;
strcpy ( drvinfo - > fw_version , " N/A " ) ;
strncpy ( drvinfo - > bus_info , pci_name ( mac - > pdev ) , 32 ) ;
}
static u32
pasemi_mac_ethtool_get_msglevel ( struct net_device * netdev )
{
struct pasemi_mac * mac = netdev_priv ( netdev ) ;
return mac - > msg_enable ;
}
static void
pasemi_mac_ethtool_set_msglevel ( struct net_device * netdev ,
u32 level )
{
struct pasemi_mac * mac = netdev_priv ( netdev ) ;
mac - > msg_enable = level ;
}
static void
pasemi_mac_ethtool_get_ringparam ( struct net_device * netdev ,
struct ethtool_ringparam * ering )
{
2008-11-13 10:38:14 +03:00
struct pasemi_mac * mac = netdev_priv ( netdev ) ;
2008-02-21 05:57:59 +03:00
ering - > tx_max_pending = TX_RING_SIZE / 2 ;
ering - > tx_pending = RING_USED ( mac - > tx ) / 2 ;
ering - > rx_max_pending = RX_RING_SIZE / 4 ;
ering - > rx_pending = RING_USED ( mac - > rx ) / 4 ;
}
static int pasemi_mac_get_sset_count ( struct net_device * netdev , int sset )
{
switch ( sset ) {
case ETH_SS_STATS :
return ARRAY_SIZE ( ethtool_stats_keys ) ;
default :
return - EOPNOTSUPP ;
}
}
static void pasemi_mac_get_ethtool_stats ( struct net_device * netdev ,
struct ethtool_stats * stats , u64 * data )
{
2008-11-13 10:38:14 +03:00
struct pasemi_mac * mac = netdev_priv ( netdev ) ;
2008-02-21 05:57:59 +03:00
int i ;
data [ 0 ] = pasemi_read_dma_reg ( PAS_DMA_RXINT_RCMDSTA ( mac - > dma_if ) )
> > PAS_DMA_RXINT_RCMDSTA_DROPS_S ;
for ( i = 0 ; i < 32 ; i + + )
data [ 1 + i ] = pasemi_read_mac_reg ( mac - > dma_if , PAS_MAC_RMON ( i ) ) ;
}
static void pasemi_mac_get_strings ( struct net_device * netdev , u32 stringset ,
u8 * data )
{
memcpy ( data , ethtool_stats_keys , sizeof ( ethtool_stats_keys ) ) ;
}
const struct ethtool_ops pasemi_mac_ethtool_ops = {
. get_settings = pasemi_mac_ethtool_get_settings ,
2009-10-12 15:25:05 +04:00
. set_settings = pasemi_mac_ethtool_set_settings ,
2008-02-21 05:57:59 +03:00
. get_drvinfo = pasemi_mac_ethtool_get_drvinfo ,
. get_msglevel = pasemi_mac_ethtool_get_msglevel ,
. set_msglevel = pasemi_mac_ethtool_set_msglevel ,
. get_link = ethtool_op_get_link ,
. get_ringparam = pasemi_mac_ethtool_get_ringparam ,
. get_strings = pasemi_mac_get_strings ,
. get_sset_count = pasemi_mac_get_sset_count ,
. get_ethtool_stats = pasemi_mac_get_ethtool_stats ,
} ;