2007-02-10 12:25:27 -02:00
# include <linux/netdevice.h>
# include <linux/ethtool.h>
# include <linux/delay.h>
# include "host.h"
# include "decl.h"
# include "defs.h"
# include "dev.h"
# include "join.h"
# include "wext.h"
static const char * mesh_stat_strings [ ] = {
" drop_duplicate_bcast " ,
" drop_ttl_zero " ,
" drop_no_fwd_route " ,
" drop_no_buffers " ,
" fwded_unicast_cnt " ,
" fwded_bcast_cnt " ,
2007-05-25 12:12:06 -04:00
" drop_blind_table " ,
" tx_failed_cnt "
2007-02-10 12:25:27 -02:00
} ;
2007-11-15 18:05:47 -05:00
static void lbs_ethtool_get_drvinfo ( struct net_device * dev ,
2007-02-10 12:25:27 -02:00
struct ethtool_drvinfo * info )
{
2007-11-23 15:43:44 +01:00
struct lbs_private * priv = ( struct lbs_private * ) dev - > priv ;
2007-02-10 12:25:27 -02:00
char fwver [ 32 ] ;
2007-11-15 18:05:47 -05:00
lbs_get_fwversion ( priv - > adapter , fwver , sizeof ( fwver ) - 1 ) ;
2007-02-10 12:25:27 -02:00
strcpy ( info - > driver , " libertas " ) ;
2007-11-15 18:05:47 -05:00
strcpy ( info - > version , lbs_driver_version ) ;
2007-02-10 12:25:27 -02:00
strcpy ( info - > fw_version , fwver ) ;
}
/* All 8388 parts have 16KiB EEPROM size at the time of writing.
* In case that changes this needs fixing .
*/
2007-11-15 18:05:47 -05:00
# define LBS_EEPROM_LEN 16384
2007-02-10 12:25:27 -02:00
2007-11-15 18:05:47 -05:00
static int lbs_ethtool_get_eeprom_len ( struct net_device * dev )
2007-02-10 12:25:27 -02:00
{
2007-11-15 18:05:47 -05:00
return LBS_EEPROM_LEN ;
2007-02-10 12:25:27 -02:00
}
2007-11-15 18:05:47 -05:00
static int lbs_ethtool_get_eeprom ( struct net_device * dev ,
2007-02-10 12:25:27 -02:00
struct ethtool_eeprom * eeprom , u8 * bytes )
{
2007-11-23 15:43:44 +01:00
struct lbs_private * priv = ( struct lbs_private * ) dev - > priv ;
struct lbs_adapter * adapter = priv - > adapter ;
2007-11-15 18:05:47 -05:00
struct lbs_ioctl_regrdwr regctrl ;
2007-02-10 12:25:27 -02:00
char * ptr ;
int ret ;
regctrl . action = 0 ;
regctrl . offset = eeprom - > offset ;
regctrl . NOB = eeprom - > len ;
2007-11-15 18:05:47 -05:00
if ( eeprom - > offset + eeprom - > len > LBS_EEPROM_LEN )
2007-02-10 12:25:27 -02:00
return - EINVAL ;
// mutex_lock(&priv->mutex);
2007-08-24 11:48:16 -04:00
adapter - > prdeeprom = kmalloc ( eeprom - > len + sizeof ( regctrl ) , GFP_KERNEL ) ;
2007-02-10 12:25:27 -02:00
if ( ! adapter - > prdeeprom )
return - ENOMEM ;
memcpy ( adapter - > prdeeprom , & regctrl , sizeof ( regctrl ) ) ;
/* +14 is for action, offset, and NOB in
* response */
2007-05-25 11:27:16 -04:00
lbs_deb_ethtool ( " action:%d offset: %x NOB: %02x \n " ,
2007-02-10 12:25:27 -02:00
regctrl . action , regctrl . offset , regctrl . NOB ) ;
2007-11-15 18:05:47 -05:00
ret = lbs_prepare_and_send_command ( priv ,
2007-08-02 11:31:18 -04:00
CMD_802_11_EEPROM_ACCESS ,
2007-02-10 12:25:27 -02:00
regctrl . action ,
2007-08-02 11:31:18 -04:00
CMD_OPTION_WAITFORRSP , 0 ,
2007-02-10 12:25:27 -02:00
& regctrl ) ;
if ( ret ) {
if ( adapter - > prdeeprom )
kfree ( adapter - > prdeeprom ) ;
2007-05-25 11:27:16 -04:00
goto done ;
2007-02-10 12:25:27 -02:00
}
mdelay ( 10 ) ;
ptr = ( char * ) adapter - > prdeeprom ;
/* skip the command header, but include the "value" u32 variable */
2007-11-15 18:05:47 -05:00
ptr = ptr + sizeof ( struct lbs_ioctl_regrdwr ) - 4 ;
2007-02-10 12:25:27 -02:00
/*
* Return the result back to the user
*/
memcpy ( bytes , ptr , eeprom - > len ) ;
if ( adapter - > prdeeprom )
kfree ( adapter - > prdeeprom ) ;
// mutex_unlock(&priv->mutex);
2007-05-25 11:27:16 -04:00
ret = 0 ;
done :
lbs_deb_enter_args ( LBS_DEB_ETHTOOL , " ret %d " , ret ) ;
return ret ;
2007-02-10 12:25:27 -02:00
}
2007-11-15 18:05:47 -05:00
static void lbs_ethtool_get_stats ( struct net_device * dev ,
2007-02-10 12:25:27 -02:00
struct ethtool_stats * stats , u64 * data )
{
2007-11-23 15:43:44 +01:00
struct lbs_private * priv = dev - > priv ;
2007-02-10 12:25:27 -02:00
struct cmd_ds_mesh_access mesh_access ;
2007-10-03 18:07:32 -07:00
int ret ;
2007-02-10 12:25:27 -02:00
2007-05-25 11:27:16 -04:00
lbs_deb_enter ( LBS_DEB_ETHTOOL ) ;
2007-02-10 12:25:27 -02:00
/* Get Mesh Statistics */
2007-11-15 18:05:47 -05:00
ret = lbs_prepare_and_send_command ( priv ,
2007-08-02 11:31:18 -04:00
CMD_MESH_ACCESS , CMD_ACT_MESH_GET_STATS ,
CMD_OPTION_WAITFORRSP , 0 , & mesh_access ) ;
2007-02-10 12:25:27 -02:00
2007-10-03 18:07:32 -07:00
if ( ret )
return ;
priv - > mstats . fwd_drop_rbt = le32_to_cpu ( mesh_access . data [ 0 ] ) ;
priv - > mstats . fwd_drop_ttl = le32_to_cpu ( mesh_access . data [ 1 ] ) ;
priv - > mstats . fwd_drop_noroute = le32_to_cpu ( mesh_access . data [ 2 ] ) ;
priv - > mstats . fwd_drop_nobuf = le32_to_cpu ( mesh_access . data [ 3 ] ) ;
priv - > mstats . fwd_unicast_cnt = le32_to_cpu ( mesh_access . data [ 4 ] ) ;
priv - > mstats . fwd_bcast_cnt = le32_to_cpu ( mesh_access . data [ 5 ] ) ;
priv - > mstats . drop_blind = le32_to_cpu ( mesh_access . data [ 6 ] ) ;
priv - > mstats . tx_failed_cnt = le32_to_cpu ( mesh_access . data [ 7 ] ) ;
data [ 0 ] = priv - > mstats . fwd_drop_rbt ;
data [ 1 ] = priv - > mstats . fwd_drop_ttl ;
data [ 2 ] = priv - > mstats . fwd_drop_noroute ;
data [ 3 ] = priv - > mstats . fwd_drop_nobuf ;
data [ 4 ] = priv - > mstats . fwd_unicast_cnt ;
data [ 5 ] = priv - > mstats . fwd_bcast_cnt ;
data [ 6 ] = priv - > mstats . drop_blind ;
data [ 7 ] = priv - > mstats . tx_failed_cnt ;
2007-02-10 12:25:27 -02:00
2007-10-03 18:07:32 -07:00
lbs_deb_enter ( LBS_DEB_ETHTOOL ) ;
}
2007-05-25 11:27:16 -04:00
2007-11-15 18:05:47 -05:00
static int lbs_ethtool_get_sset_count ( struct net_device * dev , int sset )
2007-10-03 18:07:32 -07:00
{
switch ( sset ) {
case ETH_SS_STATS :
return MESH_STATS_NUM ;
default :
return - EOPNOTSUPP ;
}
2007-02-10 12:25:27 -02:00
}
2007-11-15 18:05:47 -05:00
static void lbs_ethtool_get_strings ( struct net_device * dev ,
2007-02-10 12:25:27 -02:00
u32 stringset ,
u8 * s )
{
int i ;
2007-05-25 11:27:16 -04:00
lbs_deb_enter ( LBS_DEB_ETHTOOL ) ;
2007-02-10 12:25:27 -02:00
switch ( stringset ) {
case ETH_SS_STATS :
for ( i = 0 ; i < MESH_STATS_NUM ; i + + ) {
memcpy ( s + i * ETH_GSTRING_LEN ,
mesh_stat_strings [ i ] ,
ETH_GSTRING_LEN ) ;
}
break ;
}
2007-05-25 11:27:16 -04:00
lbs_deb_enter ( LBS_DEB_ETHTOOL ) ;
2007-02-10 12:25:27 -02:00
}
2007-11-15 18:05:47 -05:00
struct ethtool_ops lbs_ethtool_ops = {
. get_drvinfo = lbs_ethtool_get_drvinfo ,
. get_eeprom = lbs_ethtool_get_eeprom ,
. get_eeprom_len = lbs_ethtool_get_eeprom_len ,
. get_sset_count = lbs_ethtool_get_sset_count ,
. get_ethtool_stats = lbs_ethtool_get_stats ,
. get_strings = lbs_ethtool_get_strings ,
2007-02-10 12:25:27 -02:00
} ;