2008-11-28 22:19:02 +05:30
/*
2009-03-13 09:07:23 +05:30
* Copyright ( c ) 2008 - 2009 Atheros Communications Inc .
2008-11-28 22:19:02 +05:30
*
* Permission to use , copy , modify , and / or distribute this software for any
* purpose with or without fee is hereby granted , provided that the above
* copyright notice and this permission notice appear in all copies .
*
* THE SOFTWARE IS PROVIDED " AS IS " AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS . IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL , DIRECT , INDIRECT , OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE , DATA OR PROFITS , WHETHER IN AN
* ACTION OF CONTRACT , NEGLIGENCE OR OTHER TORTIOUS ACTION , ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE .
*/
2009-03-06 09:57:39 +01:00
# include <asm/unaligned.h>
2009-02-09 13:26:54 +05:30
# include "ath9k.h"
2008-11-28 22:19:02 +05:30
2009-09-23 23:06:59 -04:00
# define REG_WRITE_D(_ah, _reg, _val) \
ath9k_hw_common ( _ah ) - > ops - > write ( ( _ah ) , ( _val ) , ( _reg ) )
# define REG_READ_D(_ah, _reg) \
ath9k_hw_common ( _ah ) - > ops - > read ( ( _ah ) , ( _reg ) )
2009-03-05 16:55:18 +01:00
static struct dentry * ath9k_debugfs_root ;
2008-11-28 22:21:08 +05:30
static int ath9k_debugfs_open ( struct inode * inode , struct file * file )
{
file - > private_data = inode - > i_private ;
return 0 ;
}
2009-11-23 22:33:27 +01:00
# ifdef CONFIG_ATH_DEBUG
2009-05-27 12:48:29 +00:00
static ssize_t read_file_debug ( struct file * file , char __user * user_buf ,
size_t count , loff_t * ppos )
{
struct ath_softc * sc = file - > private_data ;
2009-09-13 02:42:02 -07:00
struct ath_common * common = ath9k_hw_common ( sc - > sc_ah ) ;
2009-05-27 12:48:29 +00:00
char buf [ 32 ] ;
2009-06-02 19:28:55 +05:30
unsigned int len ;
2009-09-13 02:42:02 -07:00
len = snprintf ( buf , sizeof ( buf ) , " 0x%08x \n " , common - > debug_mask ) ;
2009-05-27 12:48:29 +00:00
return simple_read_from_buffer ( user_buf , count , ppos , buf , len ) ;
}
static ssize_t write_file_debug ( struct file * file , const char __user * user_buf ,
size_t count , loff_t * ppos )
{
struct ath_softc * sc = file - > private_data ;
2009-09-13 02:42:02 -07:00
struct ath_common * common = ath9k_hw_common ( sc - > sc_ah ) ;
2009-05-27 12:48:29 +00:00
unsigned long mask ;
char buf [ 32 ] ;
2009-06-02 19:28:55 +05:30
ssize_t len ;
len = min ( count , sizeof ( buf ) - 1 ) ;
if ( copy_from_user ( buf , user_buf , len ) )
return - EINVAL ;
buf [ len ] = ' \0 ' ;
if ( strict_strtoul ( buf , 0 , & mask ) )
return - EINVAL ;
2009-09-13 02:42:02 -07:00
common - > debug_mask = mask ;
2009-05-27 12:48:29 +00:00
return count ;
}
static const struct file_operations fops_debug = {
. read = read_file_debug ,
. write = write_file_debug ,
. open = ath9k_debugfs_open ,
. owner = THIS_MODULE
} ;
2009-11-23 22:33:27 +01:00
# endif
2008-11-28 22:21:08 +05:30
static ssize_t read_file_dma ( struct file * file , char __user * user_buf ,
size_t count , loff_t * ppos )
{
struct ath_softc * sc = file - > private_data ;
2009-02-09 13:27:12 +05:30
struct ath_hw * ah = sc - > sc_ah ;
2008-11-28 22:21:08 +05:30
char buf [ 1024 ] ;
unsigned int len = 0 ;
u32 val [ ATH9K_NUM_DMA_DEBUG_REGS ] ;
int i , qcuOffset = 0 , dcuOffset = 0 ;
u32 * qcuBase = & val [ 0 ] , * dcuBase = & val [ 4 ] ;
2009-08-26 11:11:57 +05:30
ath9k_ps_wakeup ( sc ) ;
2009-09-23 23:06:59 -04:00
REG_WRITE_D ( ah , AR_MACMISC ,
2008-11-28 22:21:08 +05:30
( ( AR_MACMISC_DMA_OBS_LINE_8 < < AR_MACMISC_DMA_OBS_S ) |
( AR_MACMISC_MISC_OBS_BUS_1 < <
AR_MACMISC_MISC_OBS_BUS_MSB_S ) ) ) ;
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
" Raw DMA Debug values: \n " ) ;
for ( i = 0 ; i < ATH9K_NUM_DMA_DEBUG_REGS ; i + + ) {
if ( i % 4 = = 0 )
len + = snprintf ( buf + len , sizeof ( buf ) - len , " \n " ) ;
2009-09-23 23:06:59 -04:00
val [ i ] = REG_READ_D ( ah , AR_DMADBG_0 + ( i * sizeof ( u32 ) ) ) ;
2008-11-28 22:21:08 +05:30
len + = snprintf ( buf + len , sizeof ( buf ) - len , " %d: %08x " ,
i , val [ i ] ) ;
}
len + = snprintf ( buf + len , sizeof ( buf ) - len , " \n \n " ) ;
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
" Num QCU: chain_st fsp_ok fsp_st DCU: chain_st \n " ) ;
for ( i = 0 ; i < ATH9K_NUM_QUEUES ; i + + , qcuOffset + = 4 , dcuOffset + = 5 ) {
if ( i = = 8 ) {
qcuOffset = 0 ;
qcuBase + + ;
}
if ( i = = 6 ) {
dcuOffset = 0 ;
dcuBase + + ;
}
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
" %2d %2x %1x %2x %2x \n " ,
i , ( * qcuBase & ( 0x7 < < qcuOffset ) ) > > qcuOffset ,
( * qcuBase & ( 0x8 < < qcuOffset ) ) > > ( qcuOffset + 3 ) ,
val [ 2 ] & ( 0x7 < < ( i * 3 ) ) > > ( i * 3 ) ,
( * dcuBase & ( 0x1f < < dcuOffset ) ) > > dcuOffset ) ;
}
len + = snprintf ( buf + len , sizeof ( buf ) - len , " \n " ) ;
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
" qcu_stitch state: %2x qcu_fetch state: %2x \n " ,
( val [ 3 ] & 0x003c0000 ) > > 18 , ( val [ 3 ] & 0x03c00000 ) > > 22 ) ;
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
" qcu_complete state: %2x dcu_complete state: %2x \n " ,
( val [ 3 ] & 0x1c000000 ) > > 26 , ( val [ 6 ] & 0x3 ) ) ;
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
" dcu_arb state: %2x dcu_fp state: %2x \n " ,
( val [ 5 ] & 0x06000000 ) > > 25 , ( val [ 5 ] & 0x38000000 ) > > 27 ) ;
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
" chan_idle_dur: %3d chan_idle_dur_valid: %1d \n " ,
( val [ 6 ] & 0x000003fc ) > > 2 , ( val [ 6 ] & 0x00000400 ) > > 10 ) ;
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
" txfifo_valid_0: %1d txfifo_valid_1: %1d \n " ,
( val [ 6 ] & 0x00000800 ) > > 11 , ( val [ 6 ] & 0x00001000 ) > > 12 ) ;
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
" txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d \n " ,
( val [ 6 ] & 0x0001e000 ) > > 13 , ( val [ 6 ] & 0x001e0000 ) > > 17 ) ;
len + = snprintf ( buf + len , sizeof ( buf ) - len , " pcu observe: 0x%x \n " ,
2009-09-23 23:06:59 -04:00
REG_READ_D ( ah , AR_OBS_BUS_1 ) ) ;
2008-11-28 22:21:08 +05:30
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
2009-09-23 23:06:59 -04:00
" AR_CR: 0x%x \n " , REG_READ_D ( ah , AR_CR ) ) ;
2008-11-28 22:21:08 +05:30
2009-08-26 11:11:57 +05:30
ath9k_ps_restore ( sc ) ;
2008-11-28 22:21:08 +05:30
return simple_read_from_buffer ( user_buf , count , ppos , buf , len ) ;
}
static const struct file_operations fops_dma = {
. read = read_file_dma ,
. open = ath9k_debugfs_open ,
. owner = THIS_MODULE
} ;
2008-12-07 21:42:44 +05:30
void ath_debug_stat_interrupt ( struct ath_softc * sc , enum ath9k_int status )
{
if ( status )
2009-02-09 13:27:03 +05:30
sc - > debug . stats . istats . total + + ;
2008-12-07 21:42:44 +05:30
if ( status & ATH9K_INT_RX )
2009-02-09 13:27:03 +05:30
sc - > debug . stats . istats . rxok + + ;
2008-12-07 21:42:44 +05:30
if ( status & ATH9K_INT_RXEOL )
2009-02-09 13:27:03 +05:30
sc - > debug . stats . istats . rxeol + + ;
2008-12-07 21:42:44 +05:30
if ( status & ATH9K_INT_RXORN )
2009-02-09 13:27:03 +05:30
sc - > debug . stats . istats . rxorn + + ;
2008-12-07 21:42:44 +05:30
if ( status & ATH9K_INT_TX )
2009-02-09 13:27:03 +05:30
sc - > debug . stats . istats . txok + + ;
2008-12-07 21:42:44 +05:30
if ( status & ATH9K_INT_TXURN )
2009-02-09 13:27:03 +05:30
sc - > debug . stats . istats . txurn + + ;
2008-12-07 21:42:44 +05:30
if ( status & ATH9K_INT_MIB )
2009-02-09 13:27:03 +05:30
sc - > debug . stats . istats . mib + + ;
2008-12-07 21:42:44 +05:30
if ( status & ATH9K_INT_RXPHY )
2009-02-09 13:27:03 +05:30
sc - > debug . stats . istats . rxphyerr + + ;
2008-12-07 21:42:44 +05:30
if ( status & ATH9K_INT_RXKCM )
2009-02-09 13:27:03 +05:30
sc - > debug . stats . istats . rx_keycache_miss + + ;
2008-12-07 21:42:44 +05:30
if ( status & ATH9K_INT_SWBA )
2009-02-09 13:27:03 +05:30
sc - > debug . stats . istats . swba + + ;
2008-12-07 21:42:44 +05:30
if ( status & ATH9K_INT_BMISS )
2009-02-09 13:27:03 +05:30
sc - > debug . stats . istats . bmiss + + ;
2008-12-07 21:42:44 +05:30
if ( status & ATH9K_INT_BNR )
2009-02-09 13:27:03 +05:30
sc - > debug . stats . istats . bnr + + ;
2008-12-07 21:42:44 +05:30
if ( status & ATH9K_INT_CST )
2009-02-09 13:27:03 +05:30
sc - > debug . stats . istats . cst + + ;
2008-12-07 21:42:44 +05:30
if ( status & ATH9K_INT_GTT )
2009-02-09 13:27:03 +05:30
sc - > debug . stats . istats . gtt + + ;
2008-12-07 21:42:44 +05:30
if ( status & ATH9K_INT_TIM )
2009-02-09 13:27:03 +05:30
sc - > debug . stats . istats . tim + + ;
2008-12-07 21:42:44 +05:30
if ( status & ATH9K_INT_CABEND )
2009-02-09 13:27:03 +05:30
sc - > debug . stats . istats . cabend + + ;
2008-12-07 21:42:44 +05:30
if ( status & ATH9K_INT_DTIMSYNC )
2009-02-09 13:27:03 +05:30
sc - > debug . stats . istats . dtimsync + + ;
2008-12-07 21:42:44 +05:30
if ( status & ATH9K_INT_DTIM )
2009-02-09 13:27:03 +05:30
sc - > debug . stats . istats . dtim + + ;
2008-12-07 21:42:44 +05:30
}
static ssize_t read_file_interrupt ( struct file * file , char __user * user_buf ,
size_t count , loff_t * ppos )
{
struct ath_softc * sc = file - > private_data ;
char buf [ 512 ] ;
unsigned int len = 0 ;
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
2009-02-09 13:27:03 +05:30
" %8s: %10u \n " , " RX " , sc - > debug . stats . istats . rxok ) ;
2008-12-07 21:42:44 +05:30
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
2009-02-09 13:27:03 +05:30
" %8s: %10u \n " , " RXEOL " , sc - > debug . stats . istats . rxeol ) ;
2008-12-07 21:42:44 +05:30
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
2009-02-09 13:27:03 +05:30
" %8s: %10u \n " , " RXORN " , sc - > debug . stats . istats . rxorn ) ;
2008-12-07 21:42:44 +05:30
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
2009-02-09 13:27:03 +05:30
" %8s: %10u \n " , " TX " , sc - > debug . stats . istats . txok ) ;
2008-12-07 21:42:44 +05:30
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
2009-02-09 13:27:03 +05:30
" %8s: %10u \n " , " TXURN " , sc - > debug . stats . istats . txurn ) ;
2008-12-07 21:42:44 +05:30
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
2009-02-09 13:27:03 +05:30
" %8s: %10u \n " , " MIB " , sc - > debug . stats . istats . mib ) ;
2008-12-07 21:42:44 +05:30
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
2009-02-09 13:27:03 +05:30
" %8s: %10u \n " , " RXPHY " , sc - > debug . stats . istats . rxphyerr ) ;
2008-12-07 21:42:44 +05:30
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
2009-02-09 13:27:03 +05:30
" %8s: %10u \n " , " RXKCM " , sc - > debug . stats . istats . rx_keycache_miss ) ;
2008-12-07 21:42:44 +05:30
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
2009-02-09 13:27:03 +05:30
" %8s: %10u \n " , " SWBA " , sc - > debug . stats . istats . swba ) ;
2008-12-07 21:42:44 +05:30
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
2009-02-09 13:27:03 +05:30
" %8s: %10u \n " , " BMISS " , sc - > debug . stats . istats . bmiss ) ;
2008-12-07 21:42:44 +05:30
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
2009-02-09 13:27:03 +05:30
" %8s: %10u \n " , " BNR " , sc - > debug . stats . istats . bnr ) ;
2008-12-07 21:42:44 +05:30
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
2009-02-09 13:27:03 +05:30
" %8s: %10u \n " , " CST " , sc - > debug . stats . istats . cst ) ;
2008-12-07 21:42:44 +05:30
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
2009-02-09 13:27:03 +05:30
" %8s: %10u \n " , " GTT " , sc - > debug . stats . istats . gtt ) ;
2008-12-07 21:42:44 +05:30
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
2009-02-09 13:27:03 +05:30
" %8s: %10u \n " , " TIM " , sc - > debug . stats . istats . tim ) ;
2008-12-07 21:42:44 +05:30
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
2009-02-09 13:27:03 +05:30
" %8s: %10u \n " , " CABEND " , sc - > debug . stats . istats . cabend ) ;
2008-12-07 21:42:44 +05:30
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
2009-02-09 13:27:03 +05:30
" %8s: %10u \n " , " DTIMSYNC " , sc - > debug . stats . istats . dtimsync ) ;
2008-12-07 21:42:44 +05:30
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
2009-02-09 13:27:03 +05:30
" %8s: %10u \n " , " DTIM " , sc - > debug . stats . istats . dtim ) ;
2008-12-07 21:42:44 +05:30
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
2009-02-09 13:27:03 +05:30
" %8s: %10u \n " , " TOTAL " , sc - > debug . stats . istats . total ) ;
2008-12-07 21:42:44 +05:30
return simple_read_from_buffer ( user_buf , count , ppos , buf , len ) ;
}
static const struct file_operations fops_interrupt = {
. read = read_file_interrupt ,
. open = ath9k_debugfs_open ,
. owner = THIS_MODULE
} ;
2009-11-23 22:21:01 +01:00
void ath_debug_stat_rc ( struct ath_softc * sc , int final_rate )
2009-01-30 14:32:09 +05:30
{
2009-05-27 12:48:28 +00:00
struct ath_rc_stats * stats ;
2009-01-30 14:32:09 +05:30
2009-11-23 22:21:01 +01:00
stats = & sc - > debug . stats . rcstats [ final_rate ] ;
2009-05-27 12:48:28 +00:00
stats - > success + + ;
2009-01-30 14:32:09 +05:30
}
2009-02-04 08:10:26 +05:30
void ath_debug_stat_retries ( struct ath_softc * sc , int rix ,
2009-02-20 15:13:20 +05:30
int xretries , int retries , u8 per )
2009-02-04 08:10:26 +05:30
{
2009-05-27 12:48:28 +00:00
struct ath_rc_stats * stats = & sc - > debug . stats . rcstats [ rix ] ;
2009-02-04 08:10:26 +05:30
2009-05-27 12:48:28 +00:00
stats - > xretries + = xretries ;
stats - > retries + = retries ;
stats - > per = per ;
2009-02-04 08:10:26 +05:30
}
2009-05-27 12:48:28 +00:00
static ssize_t read_file_rcstat ( struct file * file , char __user * user_buf ,
size_t count , loff_t * ppos )
2009-01-30 14:32:09 +05:30
{
struct ath_softc * sc = file - > private_data ;
2009-05-27 12:48:28 +00:00
char * buf ;
unsigned int len = 0 , max ;
2009-01-30 14:32:09 +05:30
int i = 0 ;
2009-05-27 12:48:28 +00:00
ssize_t retval ;
2009-01-30 14:32:09 +05:30
2009-05-27 12:48:28 +00:00
if ( sc - > cur_rate_table = = NULL )
return 0 ;
2009-01-30 14:32:09 +05:30
2009-05-27 12:48:28 +00:00
max = 80 + sc - > cur_rate_table - > rate_cnt * 64 ;
buf = kmalloc ( max + 1 , GFP_KERNEL ) ;
if ( buf = = NULL )
return 0 ;
buf [ max ] = 0 ;
2009-01-30 14:32:09 +05:30
2009-05-27 12:48:28 +00:00
len + = sprintf ( buf , " %5s %15s %8s %9s %3s \n \n " , " Rate " , " Success " ,
" Retries " , " XRetries " , " PER " ) ;
2009-01-30 14:32:09 +05:30
for ( i = 0 ; i < sc - > cur_rate_table - > rate_cnt ; i + + ) {
2009-05-27 12:48:28 +00:00
u32 ratekbps = sc - > cur_rate_table - > info [ i ] . ratekbps ;
struct ath_rc_stats * stats = & sc - > debug . stats . rcstats [ i ] ;
len + = snprintf ( buf + len , max - len ,
" %3u.%d: %8u %8u %8u %8u \n " , ratekbps / 1000 ,
( ratekbps % 1000 ) / 100 , stats - > success ,
stats - > retries , stats - > xretries ,
stats - > per ) ;
2009-01-30 14:32:09 +05:30
}
2009-05-27 12:48:28 +00:00
retval = simple_read_from_buffer ( user_buf , count , ppos , buf , len ) ;
kfree ( buf ) ;
return retval ;
2009-01-30 14:32:09 +05:30
}
static const struct file_operations fops_rcstat = {
. read = read_file_rcstat ,
. open = ath9k_debugfs_open ,
. owner = THIS_MODULE
} ;
2009-01-23 05:44:21 +01:00
2009-03-03 19:23:40 +02:00
static const char * ath_wiphy_state_str ( enum ath_wiphy_state state )
{
switch ( state ) {
case ATH_WIPHY_INACTIVE :
return " INACTIVE " ;
case ATH_WIPHY_ACTIVE :
return " ACTIVE " ;
case ATH_WIPHY_PAUSING :
return " PAUSING " ;
case ATH_WIPHY_PAUSED :
return " PAUSED " ;
case ATH_WIPHY_SCAN :
return " SCAN " ;
}
return " ? " ;
}
static ssize_t read_file_wiphy ( struct file * file , char __user * user_buf ,
size_t count , loff_t * ppos )
{
struct ath_softc * sc = file - > private_data ;
char buf [ 512 ] ;
unsigned int len = 0 ;
int i ;
u8 addr [ ETH_ALEN ] ;
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
" primary: %s (%s chan=%d ht=%d) \n " ,
wiphy_name ( sc - > pri_wiphy - > hw - > wiphy ) ,
ath_wiphy_state_str ( sc - > pri_wiphy - > state ) ,
sc - > pri_wiphy - > chan_idx , sc - > pri_wiphy - > chan_is_ht ) ;
for ( i = 0 ; i < sc - > num_sec_wiphy ; i + + ) {
struct ath_wiphy * aphy = sc - > sec_wiphy [ i ] ;
if ( aphy = = NULL )
continue ;
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
" secondary: %s (%s chan=%d ht=%d) \n " ,
wiphy_name ( aphy - > hw - > wiphy ) ,
ath_wiphy_state_str ( aphy - > state ) ,
aphy - > chan_idx , aphy - > chan_is_ht ) ;
}
2009-09-23 23:06:59 -04:00
put_unaligned_le32 ( REG_READ_D ( sc - > sc_ah , AR_STA_ID0 ) , addr ) ;
put_unaligned_le16 ( REG_READ_D ( sc - > sc_ah , AR_STA_ID1 ) & 0xffff , addr + 4 ) ;
2009-03-03 19:23:40 +02:00
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
" addr: %pM \n " , addr ) ;
2009-09-23 23:06:59 -04:00
put_unaligned_le32 ( REG_READ_D ( sc - > sc_ah , AR_BSSMSKL ) , addr ) ;
put_unaligned_le16 ( REG_READ_D ( sc - > sc_ah , AR_BSSMSKU ) & 0xffff , addr + 4 ) ;
2009-03-03 19:23:40 +02:00
len + = snprintf ( buf + len , sizeof ( buf ) - len ,
" addrmask: %pM \n " , addr ) ;
return simple_read_from_buffer ( user_buf , count , ppos , buf , len ) ;
}
static struct ath_wiphy * get_wiphy ( struct ath_softc * sc , const char * name )
{
int i ;
if ( strcmp ( name , wiphy_name ( sc - > pri_wiphy - > hw - > wiphy ) ) = = 0 )
return sc - > pri_wiphy ;
for ( i = 0 ; i < sc - > num_sec_wiphy ; i + + ) {
struct ath_wiphy * aphy = sc - > sec_wiphy [ i ] ;
if ( aphy & & strcmp ( name , wiphy_name ( aphy - > hw - > wiphy ) ) = = 0 )
return aphy ;
}
return NULL ;
}
static int del_wiphy ( struct ath_softc * sc , const char * name )
{
struct ath_wiphy * aphy = get_wiphy ( sc , name ) ;
if ( ! aphy )
return - ENOENT ;
return ath9k_wiphy_del ( aphy ) ;
}
static int pause_wiphy ( struct ath_softc * sc , const char * name )
{
struct ath_wiphy * aphy = get_wiphy ( sc , name ) ;
if ( ! aphy )
return - ENOENT ;
return ath9k_wiphy_pause ( aphy ) ;
}
static int unpause_wiphy ( struct ath_softc * sc , const char * name )
{
struct ath_wiphy * aphy = get_wiphy ( sc , name ) ;
if ( ! aphy )
return - ENOENT ;
return ath9k_wiphy_unpause ( aphy ) ;
}
static int select_wiphy ( struct ath_softc * sc , const char * name )
{
struct ath_wiphy * aphy = get_wiphy ( sc , name ) ;
if ( ! aphy )
return - ENOENT ;
return ath9k_wiphy_select ( aphy ) ;
}
static int schedule_wiphy ( struct ath_softc * sc , const char * msec )
{
ath9k_wiphy_set_scheduler ( sc , simple_strtoul ( msec , NULL , 0 ) ) ;
return 0 ;
}
static ssize_t write_file_wiphy ( struct file * file , const char __user * user_buf ,
size_t count , loff_t * ppos )
{
struct ath_softc * sc = file - > private_data ;
char buf [ 50 ] ;
size_t len ;
len = min ( count , sizeof ( buf ) - 1 ) ;
if ( copy_from_user ( buf , user_buf , len ) )
return - EFAULT ;
buf [ len ] = ' \0 ' ;
if ( len > 0 & & buf [ len - 1 ] = = ' \n ' )
buf [ len - 1 ] = ' \0 ' ;
if ( strncmp ( buf , " add " , 3 ) = = 0 ) {
int res = ath9k_wiphy_add ( sc ) ;
if ( res < 0 )
return res ;
} else if ( strncmp ( buf , " del= " , 4 ) = = 0 ) {
int res = del_wiphy ( sc , buf + 4 ) ;
if ( res < 0 )
return res ;
} else if ( strncmp ( buf , " pause= " , 6 ) = = 0 ) {
int res = pause_wiphy ( sc , buf + 6 ) ;
if ( res < 0 )
return res ;
} else if ( strncmp ( buf , " unpause= " , 8 ) = = 0 ) {
int res = unpause_wiphy ( sc , buf + 8 ) ;
if ( res < 0 )
return res ;
} else if ( strncmp ( buf , " select= " , 7 ) = = 0 ) {
int res = select_wiphy ( sc , buf + 7 ) ;
if ( res < 0 )
return res ;
} else if ( strncmp ( buf , " schedule= " , 9 ) = = 0 ) {
int res = schedule_wiphy ( sc , buf + 9 ) ;
if ( res < 0 )
return res ;
} else
return - EOPNOTSUPP ;
return count ;
}
static const struct file_operations fops_wiphy = {
. read = read_file_wiphy ,
. write = write_file_wiphy ,
. open = ath9k_debugfs_open ,
. owner = THIS_MODULE
} ;
2009-07-27 12:08:16 +05:30
# define PR(str, elem) \
do { \
len + = snprintf ( buf + len , size - len , \
" %s%13u%11u%10u%10u \n " , str , \
sc - > debug . stats . txstats [ sc - > tx . hwq_map [ ATH9K_WME_AC_BE ] ] . elem , \
sc - > debug . stats . txstats [ sc - > tx . hwq_map [ ATH9K_WME_AC_BK ] ] . elem , \
sc - > debug . stats . txstats [ sc - > tx . hwq_map [ ATH9K_WME_AC_VI ] ] . elem , \
sc - > debug . stats . txstats [ sc - > tx . hwq_map [ ATH9K_WME_AC_VO ] ] . elem ) ; \
} while ( 0 )
static ssize_t read_file_xmit ( struct file * file , char __user * user_buf ,
size_t count , loff_t * ppos )
{
struct ath_softc * sc = file - > private_data ;
char * buf ;
unsigned int len = 0 , size = 2048 ;
ssize_t retval = 0 ;
buf = kzalloc ( size , GFP_KERNEL ) ;
if ( buf = = NULL )
return 0 ;
len + = sprintf ( buf , " %30s %10s%10s%10s \n \n " , " BE " , " BK " , " VI " , " VO " ) ;
PR ( " MPDUs Queued: " , queued ) ;
PR ( " MPDUs Completed: " , completed ) ;
PR ( " Aggregates: " , a_aggr ) ;
PR ( " AMPDUs Queued: " , a_queued ) ;
PR ( " AMPDUs Completed: " , a_completed ) ;
PR ( " AMPDUs Retried: " , a_retries ) ;
PR ( " AMPDUs XRetried: " , a_xretries ) ;
PR ( " FIFO Underrun: " , fifo_underrun ) ;
PR ( " TXOP Exceeded: " , xtxop ) ;
PR ( " TXTIMER Expiry: " , timer_exp ) ;
PR ( " DESC CFG Error: " , desc_cfg_err ) ;
PR ( " DATA Underrun: " , data_underrun ) ;
PR ( " DELIM Underrun: " , delim_underrun ) ;
retval = simple_read_from_buffer ( user_buf , count , ppos , buf , len ) ;
kfree ( buf ) ;
return retval ;
}
void ath_debug_stat_tx ( struct ath_softc * sc , struct ath_txq * txq ,
struct ath_buf * bf )
{
struct ath_desc * ds = bf - > bf_desc ;
if ( bf_isampdu ( bf ) ) {
if ( bf_isxretried ( bf ) )
TX_STAT_INC ( txq - > axq_qnum , a_xretries ) ;
else
TX_STAT_INC ( txq - > axq_qnum , a_completed ) ;
} else {
TX_STAT_INC ( txq - > axq_qnum , completed ) ;
}
if ( ds - > ds_txstat . ts_status & ATH9K_TXERR_FIFO )
TX_STAT_INC ( txq - > axq_qnum , fifo_underrun ) ;
if ( ds - > ds_txstat . ts_status & ATH9K_TXERR_XTXOP )
TX_STAT_INC ( txq - > axq_qnum , xtxop ) ;
if ( ds - > ds_txstat . ts_status & ATH9K_TXERR_TIMER_EXPIRED )
TX_STAT_INC ( txq - > axq_qnum , timer_exp ) ;
if ( ds - > ds_txstat . ts_flags & ATH9K_TX_DESC_CFG_ERR )
TX_STAT_INC ( txq - > axq_qnum , desc_cfg_err ) ;
if ( ds - > ds_txstat . ts_flags & ATH9K_TX_DATA_UNDERRUN )
TX_STAT_INC ( txq - > axq_qnum , data_underrun ) ;
if ( ds - > ds_txstat . ts_flags & ATH9K_TX_DELIM_UNDERRUN )
TX_STAT_INC ( txq - > axq_qnum , delim_underrun ) ;
}
static const struct file_operations fops_xmit = {
. read = read_file_xmit ,
. open = ath9k_debugfs_open ,
. owner = THIS_MODULE
} ;
2009-03-03 19:23:40 +02:00
2009-09-07 04:52:26 -07:00
int ath9k_init_debug ( struct ath_hw * ah )
2008-11-28 22:19:02 +05:30
{
2009-09-28 02:54:40 -04:00
struct ath_common * common = ath9k_hw_common ( ah ) ;
struct ath_softc * sc = ( struct ath_softc * ) common - > priv ;
2009-09-07 04:52:26 -07:00
2009-03-30 15:28:42 +05:30
if ( ! ath9k_debugfs_root )
return - ENOENT ;
2009-02-09 13:27:03 +05:30
sc - > debug . debugfs_phy = debugfs_create_dir ( wiphy_name ( sc - > hw - > wiphy ) ,
2009-03-05 16:55:18 +01:00
ath9k_debugfs_root ) ;
2009-02-09 13:27:03 +05:30
if ( ! sc - > debug . debugfs_phy )
2008-11-28 22:20:23 +05:30
goto err ;
2009-11-23 22:33:27 +01:00
# ifdef CONFIG_ATH_DEBUG
2009-05-27 12:48:29 +00:00
sc - > debug . debugfs_debug = debugfs_create_file ( " debug " ,
2009-06-28 23:25:28 +02:00
S_IRUSR | S_IWUSR , sc - > debug . debugfs_phy , sc , & fops_debug ) ;
2009-05-27 12:48:29 +00:00
if ( ! sc - > debug . debugfs_debug )
goto err ;
2009-11-23 22:33:27 +01:00
# endif
2009-05-27 12:48:29 +00:00
2009-06-28 23:25:28 +02:00
sc - > debug . debugfs_dma = debugfs_create_file ( " dma " , S_IRUSR ,
2009-02-09 13:27:03 +05:30
sc - > debug . debugfs_phy , sc , & fops_dma ) ;
if ( ! sc - > debug . debugfs_dma )
2008-11-28 22:21:08 +05:30
goto err ;
2009-02-09 13:27:03 +05:30
sc - > debug . debugfs_interrupt = debugfs_create_file ( " interrupt " ,
2009-06-28 23:25:28 +02:00
S_IRUSR ,
2009-02-09 13:27:03 +05:30
sc - > debug . debugfs_phy ,
2008-12-07 21:42:44 +05:30
sc , & fops_interrupt ) ;
2009-02-09 13:27:03 +05:30
if ( ! sc - > debug . debugfs_interrupt )
2008-12-07 21:42:44 +05:30
goto err ;
2009-02-09 13:27:03 +05:30
sc - > debug . debugfs_rcstat = debugfs_create_file ( " rcstat " ,
2009-06-28 23:25:28 +02:00
S_IRUSR ,
2009-02-09 13:27:03 +05:30
sc - > debug . debugfs_phy ,
2009-01-30 14:32:09 +05:30
sc , & fops_rcstat ) ;
2009-02-09 13:27:03 +05:30
if ( ! sc - > debug . debugfs_rcstat )
2009-01-30 14:32:09 +05:30
goto err ;
2009-03-03 19:23:40 +02:00
sc - > debug . debugfs_wiphy = debugfs_create_file (
2009-06-28 23:25:28 +02:00
" wiphy " , S_IRUSR | S_IWUSR , sc - > debug . debugfs_phy , sc ,
2009-03-03 19:23:40 +02:00
& fops_wiphy ) ;
if ( ! sc - > debug . debugfs_wiphy )
goto err ;
2009-07-27 12:08:16 +05:30
sc - > debug . debugfs_xmit = debugfs_create_file ( " xmit " ,
S_IRUSR ,
sc - > debug . debugfs_phy ,
sc , & fops_xmit ) ;
if ( ! sc - > debug . debugfs_xmit )
goto err ;
2008-11-28 22:20:23 +05:30
return 0 ;
err :
2009-09-07 04:52:26 -07:00
ath9k_exit_debug ( ah ) ;
2008-11-28 22:20:23 +05:30
return - ENOMEM ;
}
2009-09-07 04:52:26 -07:00
void ath9k_exit_debug ( struct ath_hw * ah )
2008-11-28 22:20:23 +05:30
{
2009-09-28 02:54:40 -04:00
struct ath_common * common = ath9k_hw_common ( ah ) ;
struct ath_softc * sc = ( struct ath_softc * ) common - > priv ;
2009-09-07 04:52:26 -07:00
2009-07-27 12:08:16 +05:30
debugfs_remove ( sc - > debug . debugfs_xmit ) ;
2009-03-03 19:23:40 +02:00
debugfs_remove ( sc - > debug . debugfs_wiphy ) ;
2009-02-09 13:27:03 +05:30
debugfs_remove ( sc - > debug . debugfs_rcstat ) ;
debugfs_remove ( sc - > debug . debugfs_interrupt ) ;
debugfs_remove ( sc - > debug . debugfs_dma ) ;
2009-05-27 12:48:29 +00:00
debugfs_remove ( sc - > debug . debugfs_debug ) ;
2009-02-09 13:27:03 +05:30
debugfs_remove ( sc - > debug . debugfs_phy ) ;
2009-03-05 16:55:18 +01:00
}
int ath9k_debug_create_root ( void )
{
ath9k_debugfs_root = debugfs_create_dir ( KBUILD_MODNAME , NULL ) ;
if ( ! ath9k_debugfs_root )
return - ENOENT ;
return 0 ;
}
void ath9k_debug_remove_root ( void )
{
debugfs_remove ( ath9k_debugfs_root ) ;
ath9k_debugfs_root = NULL ;
2008-11-28 22:19:02 +05:30
}