2013-01-24 14:25:36 +01:00
/******************************************************************************
*
* This file is provided under a dual BSD / GPLv2 license . When using or
* redistributing this file , you may do so under either license .
*
* GPL LICENSE SUMMARY
*
2013-12-30 13:15:54 +02:00
* Copyright ( c ) 2012 - 2014 Intel Corporation . All rights reserved .
2014-07-24 14:05:26 +02:00
* Copyright ( c ) 2013 - 2014 Intel Mobile Communications GmbH
2013-01-24 14:25:36 +01:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of version 2 of the GNU General Public License 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 . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 ,
* USA
*
* The full GNU General Public License is included in this distribution
2013-02-18 09:22:28 +02:00
* in the file called COPYING .
2013-01-24 14:25:36 +01:00
*
* Contact Information :
* Intel Linux Wireless < ilw @ linux . intel . com >
* Intel Corporation , 5200 N . E . Elam Young Parkway , Hillsboro , OR 97124 - 6497
*
* BSD LICENSE
*
2013-12-30 13:15:54 +02:00
* Copyright ( c ) 2012 - 2014 Intel Corporation . All rights reserved .
2014-07-24 14:05:26 +02:00
* Copyright ( c ) 2013 - 2014 Intel Mobile Communications GmbH
2013-01-24 14:25:36 +01:00
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
*
* * Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* * Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in
* the documentation and / or other materials provided with the
* distribution .
* * Neither the name Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* " AS IS " AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT
* LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL ,
* SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT
* LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2014-03-19 08:25:05 +02:00
# include <linux/vmalloc.h>
2013-01-24 14:25:36 +01:00
# include "mvm.h"
# include "sta.h"
# include "iwl-io.h"
2013-11-12 16:58:41 +01:00
# include "debugfs.h"
2014-04-24 10:41:31 +02:00
# include "iwl-fw-error-dump.h"
2013-01-24 14:25:36 +01:00
2013-11-13 09:10:21 +01:00
static ssize_t iwl_dbgfs_tx_flush_write ( struct iwl_mvm * mvm , char * buf ,
2013-01-24 14:25:36 +01:00
size_t count , loff_t * ppos )
{
2013-11-12 16:48:03 +01:00
int ret ;
2013-01-24 14:25:36 +01:00
u32 scd_q_msk ;
if ( ! mvm - > ucode_loaded | | mvm - > cur_ucode ! = IWL_UCODE_REGULAR )
return - EIO ;
if ( sscanf ( buf , " %x " , & scd_q_msk ) ! = 1 )
return - EINVAL ;
IWL_ERR ( mvm , " FLUSHING queues: scd_q_msk = 0x%x \n " , scd_q_msk ) ;
mutex_lock ( & mvm - > mutex ) ;
ret = iwl_mvm_flush_tx_path ( mvm , scd_q_msk , true ) ? : count ;
mutex_unlock ( & mvm - > mutex ) ;
return ret ;
}
2013-11-13 09:10:21 +01:00
static ssize_t iwl_dbgfs_sta_drain_write ( struct iwl_mvm * mvm , char * buf ,
2013-01-24 14:25:36 +01:00
size_t count , loff_t * ppos )
{
2014-01-14 08:30:32 +02:00
struct iwl_mvm_sta * mvmsta ;
2013-11-12 16:48:03 +01:00
int sta_id , drain , ret ;
2013-01-24 14:25:36 +01:00
if ( ! mvm - > ucode_loaded | | mvm - > cur_ucode ! = IWL_UCODE_REGULAR )
return - EIO ;
if ( sscanf ( buf , " %d %d " , & sta_id , & drain ) ! = 2 )
return - EINVAL ;
2013-10-25 13:06:06 +02:00
if ( sta_id < 0 | | sta_id > = IWL_MVM_STATION_COUNT )
return - EINVAL ;
if ( drain < 0 | | drain > 1 )
return - EINVAL ;
2013-01-24 14:25:36 +01:00
mutex_lock ( & mvm - > mutex ) ;
2014-01-14 08:30:32 +02:00
mvmsta = iwl_mvm_sta_from_staid_protected ( mvm , sta_id ) ;
if ( ! mvmsta )
2013-01-24 14:25:36 +01:00
ret = - ENOENT ;
else
2014-01-14 08:30:32 +02:00
ret = iwl_mvm_drain_sta ( mvm , mvmsta , drain ) ? : count ;
2013-01-24 14:25:36 +01:00
mutex_unlock ( & mvm - > mutex ) ;
return ret ;
}
2014-03-18 21:15:06 +02:00
static int iwl_dbgfs_fw_error_dump_open ( struct inode * inode , struct file * file )
{
struct iwl_mvm * mvm = inode - > i_private ;
int ret ;
if ( ! mvm )
return - EINVAL ;
mutex_lock ( & mvm - > mutex ) ;
if ( ! mvm - > fw_error_dump ) {
ret = - ENODATA ;
goto out ;
}
file - > private_data = mvm - > fw_error_dump ;
mvm - > fw_error_dump = NULL ;
ret = 0 ;
out :
mutex_unlock ( & mvm - > mutex ) ;
return ret ;
}
static ssize_t iwl_dbgfs_fw_error_dump_read ( struct file * file ,
char __user * user_buf ,
size_t count , loff_t * ppos )
{
2014-07-08 19:45:17 +03:00
struct iwl_mvm_dump_ptrs * dump_ptrs = ( void * ) file - > private_data ;
ssize_t bytes_read = 0 ;
ssize_t bytes_read_trans = 0 ;
if ( * ppos < dump_ptrs - > op_mode_len )
bytes_read + =
simple_read_from_buffer ( user_buf , count , ppos ,
dump_ptrs - > op_mode_ptr ,
dump_ptrs - > op_mode_len ) ;
if ( bytes_read < 0 | | * ppos < dump_ptrs - > op_mode_len )
return bytes_read ;
if ( dump_ptrs - > trans_ptr ) {
* ppos - = dump_ptrs - > op_mode_len ;
bytes_read_trans =
simple_read_from_buffer ( user_buf + bytes_read ,
count - bytes_read , ppos ,
dump_ptrs - > trans_ptr - > data ,
dump_ptrs - > trans_ptr - > len ) ;
* ppos + = dump_ptrs - > op_mode_len ;
if ( bytes_read_trans > = 0 )
bytes_read + = bytes_read_trans ;
else if ( ! bytes_read )
/* propagate the failure */
return bytes_read_trans ;
}
return bytes_read ;
2014-03-18 21:15:06 +02:00
}
static int iwl_dbgfs_fw_error_dump_release ( struct inode * inode ,
struct file * file )
{
2014-07-08 19:45:17 +03:00
struct iwl_mvm_dump_ptrs * dump_ptrs = ( void * ) file - > private_data ;
vfree ( dump_ptrs - > op_mode_ptr ) ;
vfree ( dump_ptrs - > trans_ptr ) ;
kfree ( dump_ptrs ) ;
2014-03-18 21:15:06 +02:00
return 0 ;
}
2013-01-24 14:25:36 +01:00
static ssize_t iwl_dbgfs_sram_read ( struct file * file , char __user * user_buf ,
size_t count , loff_t * ppos )
{
struct iwl_mvm * mvm = file - > private_data ;
const struct fw_img * img ;
2013-12-24 14:58:29 +02:00
unsigned int ofs , len ;
size_t ret ;
2013-01-24 14:25:36 +01:00
u8 * ptr ;
2013-05-15 13:08:51 +02:00
if ( ! mvm - > ucode_loaded )
return - EINVAL ;
2013-01-24 14:25:36 +01:00
/* default is to dump the entire data segment */
2013-12-24 14:58:29 +02:00
img = & mvm - > fw - > img [ mvm - > cur_ucode ] ;
ofs = img - > sec [ IWL_UCODE_SECTION_DATA ] . offset ;
len = img - > sec [ IWL_UCODE_SECTION_DATA ] . len ;
2014-01-06 09:05:54 +02:00
if ( mvm - > dbgfs_sram_len ) {
2013-05-15 13:08:51 +02:00
ofs = mvm - > dbgfs_sram_offset ;
len = mvm - > dbgfs_sram_len ;
2013-01-24 14:25:36 +01:00
}
ptr = kzalloc ( len , GFP_KERNEL ) ;
2013-12-24 14:58:29 +02:00
if ( ! ptr )
2013-01-24 14:25:36 +01:00
return - ENOMEM ;
2013-05-15 13:08:51 +02:00
iwl_trans_read_mem_bytes ( mvm - > trans , ofs , ptr , len ) ;
2013-01-24 14:25:36 +01:00
2013-12-24 14:58:29 +02:00
ret = simple_read_from_buffer ( user_buf , count , ppos , ptr , len ) ;
2013-01-24 14:25:36 +01:00
kfree ( ptr ) ;
return ret ;
}
2013-11-13 09:10:21 +01:00
static ssize_t iwl_dbgfs_sram_write ( struct iwl_mvm * mvm , char * buf ,
size_t count , loff_t * ppos )
2013-01-24 14:25:36 +01:00
{
2013-12-24 14:58:29 +02:00
const struct fw_img * img ;
2013-01-24 14:25:36 +01:00
u32 offset , len ;
2013-12-24 14:58:29 +02:00
u32 img_offset , img_len ;
if ( ! mvm - > ucode_loaded )
return - EINVAL ;
img = & mvm - > fw - > img [ mvm - > cur_ucode ] ;
img_offset = img - > sec [ IWL_UCODE_SECTION_DATA ] . offset ;
img_len = img - > sec [ IWL_UCODE_SECTION_DATA ] . len ;
2013-01-24 14:25:36 +01:00
if ( sscanf ( buf , " %x,%x " , & offset , & len ) = = 2 ) {
if ( ( offset & 0x3 ) | | ( len & 0x3 ) )
return - EINVAL ;
2013-12-24 14:58:29 +02:00
if ( offset + len > img_offset + img_len )
return - EINVAL ;
2013-01-24 14:25:36 +01:00
mvm - > dbgfs_sram_offset = offset ;
mvm - > dbgfs_sram_len = len ;
} else {
mvm - > dbgfs_sram_offset = 0 ;
mvm - > dbgfs_sram_len = 0 ;
}
return count ;
}
2014-07-17 16:41:14 +03:00
static ssize_t iwl_dbgfs_set_nic_temperature_read ( struct file * file ,
char __user * user_buf ,
size_t count , loff_t * ppos )
{
struct iwl_mvm * mvm = file - > private_data ;
char buf [ 16 ] ;
int pos ;
if ( ! mvm - > temperature_test )
pos = scnprintf ( buf , sizeof ( buf ) , " disabled \n " ) ;
else
pos = scnprintf ( buf , sizeof ( buf ) , " %d \n " , mvm - > temperature ) ;
return simple_read_from_buffer ( user_buf , count , ppos , buf , pos ) ;
}
/*
* Set NIC Temperature
* Cause the driver to ignore the actual NIC temperature reported by the FW
* Enable : any value between IWL_MVM_DEBUG_SET_TEMPERATURE_MIN -
* IWL_MVM_DEBUG_SET_TEMPERATURE_MAX
* Disable : IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE
*/
static ssize_t iwl_dbgfs_set_nic_temperature_write ( struct iwl_mvm * mvm ,
char * buf , size_t count ,
loff_t * ppos )
{
int temperature ;
2014-08-20 10:21:07 +03:00
if ( ! mvm - > ucode_loaded & & ! mvm - > temperature_test )
return - EIO ;
2014-07-17 16:41:14 +03:00
if ( kstrtoint ( buf , 10 , & temperature ) )
return - EINVAL ;
/* not a legal temperature */
if ( ( temperature > IWL_MVM_DEBUG_SET_TEMPERATURE_MAX & &
temperature ! = IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE ) | |
temperature < IWL_MVM_DEBUG_SET_TEMPERATURE_MIN )
return - EINVAL ;
mutex_lock ( & mvm - > mutex ) ;
if ( temperature = = IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE ) {
2014-08-20 17:26:58 +03:00
if ( ! mvm - > temperature_test )
goto out ;
2014-07-17 16:41:14 +03:00
mvm - > temperature_test = false ;
2014-08-20 17:26:58 +03:00
/* Since we can't read the temp while awake, just set
* it to zero until we get the next RX stats from the
* firmware .
*/
mvm - > temperature = 0 ;
2014-07-17 16:41:14 +03:00
} else {
mvm - > temperature_test = true ;
mvm - > temperature = temperature ;
}
IWL_DEBUG_TEMP ( mvm , " %sabling debug set temperature (temp = %d) \n " ,
mvm - > temperature_test ? " En " : " Dis " ,
mvm - > temperature ) ;
/* handle the temperature change */
iwl_mvm_tt_handler ( mvm ) ;
2014-08-20 17:26:58 +03:00
out :
2014-07-17 16:41:14 +03:00
mutex_unlock ( & mvm - > mutex ) ;
return count ;
}
2013-01-24 14:25:36 +01:00
static ssize_t iwl_dbgfs_stations_read ( struct file * file , char __user * user_buf ,
size_t count , loff_t * ppos )
{
struct iwl_mvm * mvm = file - > private_data ;
struct ieee80211_sta * sta ;
char buf [ 400 ] ;
int i , pos = 0 , bufsz = sizeof ( buf ) ;
mutex_lock ( & mvm - > mutex ) ;
for ( i = 0 ; i < IWL_MVM_STATION_COUNT ; i + + ) {
pos + = scnprintf ( buf + pos , bufsz - pos , " %.2d: " , i ) ;
sta = rcu_dereference_protected ( mvm - > fw_id_to_mac_id [ i ] ,
lockdep_is_held ( & mvm - > mutex ) ) ;
if ( ! sta )
pos + = scnprintf ( buf + pos , bufsz - pos , " N/A \n " ) ;
else if ( IS_ERR ( sta ) )
pos + = scnprintf ( buf + pos , bufsz - pos , " %ld \n " ,
PTR_ERR ( sta ) ) ;
else
pos + = scnprintf ( buf + pos , bufsz - pos , " %pM \n " ,
sta - > addr ) ;
}
mutex_unlock ( & mvm - > mutex ) ;
return simple_read_from_buffer ( user_buf , count , ppos , buf , pos ) ;
}
2013-09-03 14:18:03 +03:00
static ssize_t iwl_dbgfs_disable_power_off_read ( struct file * file ,
char __user * user_buf ,
2013-01-24 14:25:36 +01:00
size_t count , loff_t * ppos )
{
struct iwl_mvm * mvm = file - > private_data ;
2013-09-03 14:18:03 +03:00
char buf [ 64 ] ;
int bufsz = sizeof ( buf ) ;
int pos = 0 ;
2013-01-24 14:25:36 +01:00
2013-09-03 14:18:03 +03:00
pos + = scnprintf ( buf + pos , bufsz - pos , " disable_power_off_d0=%d \n " ,
mvm - > disable_power_off ) ;
pos + = scnprintf ( buf + pos , bufsz - pos , " disable_power_off_d3=%d \n " ,
mvm - > disable_power_off_d3 ) ;
2013-01-24 14:25:36 +01:00
2013-09-03 14:18:03 +03:00
return simple_read_from_buffer ( user_buf , count , ppos , buf , pos ) ;
2013-01-24 14:25:36 +01:00
}
2013-11-13 09:10:21 +01:00
static ssize_t iwl_dbgfs_disable_power_off_write ( struct iwl_mvm * mvm , char * buf ,
2013-09-03 14:18:03 +03:00
size_t count , loff_t * ppos )
2013-01-24 14:25:36 +01:00
{
2013-11-13 09:10:21 +01:00
int ret , val ;
2013-09-03 14:18:03 +03:00
if ( ! mvm - > ucode_loaded )
return - EIO ;
2013-01-24 14:25:36 +01:00
2013-09-03 14:18:03 +03:00
if ( ! strncmp ( " disable_power_off_d0= " , buf , 21 ) ) {
if ( sscanf ( buf + 21 , " %d " , & val ) ! = 1 )
return - EINVAL ;
mvm - > disable_power_off = val ;
} else if ( ! strncmp ( " disable_power_off_d3= " , buf , 21 ) ) {
if ( sscanf ( buf + 21 , " %d " , & val ) ! = 1 )
return - EINVAL ;
mvm - > disable_power_off_d3 = val ;
} else {
2013-01-24 14:25:36 +01:00
return - EINVAL ;
2013-09-03 14:18:03 +03:00
}
2013-01-24 14:25:36 +01:00
2013-09-03 14:18:03 +03:00
mutex_lock ( & mvm - > mutex ) ;
2014-01-28 10:17:18 +02:00
ret = iwl_mvm_power_update_device ( mvm ) ;
2013-09-03 14:18:03 +03:00
mutex_unlock ( & mvm - > mutex ) ;
2013-01-24 14:25:36 +01:00
2013-09-03 14:18:03 +03:00
return ret ? : count ;
2013-01-24 14:25:36 +01:00
}
2013-02-19 11:02:36 +02:00
# define BT_MBOX_MSG(_notif, _num, _field) \
( ( le32_to_cpu ( ( _notif ) - > mbox_msg [ ( _num ) ] ) & BT_MBOX # # _num # # _ # # _field ) \
> > BT_MBOX # # _num # # _ # # _field # # _POS )
# define BT_MBOX_PRINT(_num, _field, _end) \
pos + = scnprintf ( buf + pos , bufsz - pos , \
" \t %s: %d%s " , \
# _field, \
BT_MBOX_MSG ( notif , _num , _field ) , \
true ? " \n " : " , " ) ;
2014-07-02 17:33:52 +03:00
static
int iwl_mvm_coex_dump_mbox ( struct iwl_bt_coex_profile_notif * notif , char * buf ,
int pos , int bufsz )
2013-02-19 11:02:36 +02:00
{
2014-07-02 17:33:52 +03:00
pos + = scnprintf ( buf + pos , bufsz - pos , " MBOX dw0: \n " ) ;
2013-02-19 11:02:36 +02:00
2014-07-02 17:33:52 +03:00
BT_MBOX_PRINT ( 0 , LE_SLAVE_LAT , false ) ;
BT_MBOX_PRINT ( 0 , LE_PROF1 , false ) ;
BT_MBOX_PRINT ( 0 , LE_PROF2 , false ) ;
BT_MBOX_PRINT ( 0 , LE_PROF_OTHER , false ) ;
BT_MBOX_PRINT ( 0 , CHL_SEQ_N , false ) ;
BT_MBOX_PRINT ( 0 , INBAND_S , false ) ;
BT_MBOX_PRINT ( 0 , LE_MIN_RSSI , false ) ;
BT_MBOX_PRINT ( 0 , LE_SCAN , false ) ;
BT_MBOX_PRINT ( 0 , LE_ADV , false ) ;
BT_MBOX_PRINT ( 0 , LE_MAX_TX_POWER , false ) ;
BT_MBOX_PRINT ( 0 , OPEN_CON_1 , true ) ;
2013-02-19 11:02:36 +02:00
2014-07-02 17:33:52 +03:00
pos + = scnprintf ( buf + pos , bufsz - pos , " MBOX dw1: \n " ) ;
BT_MBOX_PRINT ( 1 , BR_MAX_TX_POWER , false ) ;
BT_MBOX_PRINT ( 1 , IP_SR , false ) ;
BT_MBOX_PRINT ( 1 , LE_MSTR , false ) ;
BT_MBOX_PRINT ( 1 , AGGR_TRFC_LD , false ) ;
BT_MBOX_PRINT ( 1 , MSG_TYPE , false ) ;
BT_MBOX_PRINT ( 1 , SSN , true ) ;
pos + = scnprintf ( buf + pos , bufsz - pos , " MBOX dw2: \n " ) ;
BT_MBOX_PRINT ( 2 , SNIFF_ACT , false ) ;
BT_MBOX_PRINT ( 2 , PAG , false ) ;
BT_MBOX_PRINT ( 2 , INQUIRY , false ) ;
BT_MBOX_PRINT ( 2 , CONN , false ) ;
BT_MBOX_PRINT ( 2 , SNIFF_INTERVAL , false ) ;
BT_MBOX_PRINT ( 2 , DISC , false ) ;
BT_MBOX_PRINT ( 2 , SCO_TX_ACT , false ) ;
BT_MBOX_PRINT ( 2 , SCO_RX_ACT , false ) ;
BT_MBOX_PRINT ( 2 , ESCO_RE_TX , false ) ;
BT_MBOX_PRINT ( 2 , SCO_DURATION , true ) ;
2013-02-19 11:02:36 +02:00
2014-07-02 17:33:52 +03:00
pos + = scnprintf ( buf + pos , bufsz - pos , " MBOX dw3: \n " ) ;
BT_MBOX_PRINT ( 3 , SCO_STATE , false ) ;
BT_MBOX_PRINT ( 3 , SNIFF_STATE , false ) ;
BT_MBOX_PRINT ( 3 , A2DP_STATE , false ) ;
BT_MBOX_PRINT ( 3 , ACL_STATE , false ) ;
BT_MBOX_PRINT ( 3 , MSTR_STATE , false ) ;
BT_MBOX_PRINT ( 3 , OBX_STATE , false ) ;
BT_MBOX_PRINT ( 3 , OPEN_CON_2 , false ) ;
BT_MBOX_PRINT ( 3 , TRAFFIC_LOAD , false ) ;
BT_MBOX_PRINT ( 3 , CHL_SEQN_LSB , false ) ;
BT_MBOX_PRINT ( 3 , INBAND_P , false ) ;
BT_MBOX_PRINT ( 3 , MSG_TYPE_2 , false ) ;
BT_MBOX_PRINT ( 3 , SSN_2 , false ) ;
BT_MBOX_PRINT ( 3 , UPDATE_REQUEST , true ) ;
return pos ;
}
static
int iwl_mvm_coex_dump_mbox_old ( struct iwl_bt_coex_profile_notif_old * notif ,
char * buf , int pos , int bufsz )
{
2013-02-19 11:02:36 +02:00
pos + = scnprintf ( buf + pos , bufsz - pos , " MBOX dw0: \n " ) ;
BT_MBOX_PRINT ( 0 , LE_SLAVE_LAT , false ) ;
BT_MBOX_PRINT ( 0 , LE_PROF1 , false ) ;
BT_MBOX_PRINT ( 0 , LE_PROF2 , false ) ;
BT_MBOX_PRINT ( 0 , LE_PROF_OTHER , false ) ;
BT_MBOX_PRINT ( 0 , CHL_SEQ_N , false ) ;
BT_MBOX_PRINT ( 0 , INBAND_S , false ) ;
BT_MBOX_PRINT ( 0 , LE_MIN_RSSI , false ) ;
BT_MBOX_PRINT ( 0 , LE_SCAN , false ) ;
BT_MBOX_PRINT ( 0 , LE_ADV , false ) ;
BT_MBOX_PRINT ( 0 , LE_MAX_TX_POWER , false ) ;
BT_MBOX_PRINT ( 0 , OPEN_CON_1 , true ) ;
pos + = scnprintf ( buf + pos , bufsz - pos , " MBOX dw1: \n " ) ;
BT_MBOX_PRINT ( 1 , BR_MAX_TX_POWER , false ) ;
BT_MBOX_PRINT ( 1 , IP_SR , false ) ;
BT_MBOX_PRINT ( 1 , LE_MSTR , false ) ;
BT_MBOX_PRINT ( 1 , AGGR_TRFC_LD , false ) ;
BT_MBOX_PRINT ( 1 , MSG_TYPE , false ) ;
BT_MBOX_PRINT ( 1 , SSN , true ) ;
pos + = scnprintf ( buf + pos , bufsz - pos , " MBOX dw2: \n " ) ;
BT_MBOX_PRINT ( 2 , SNIFF_ACT , false ) ;
BT_MBOX_PRINT ( 2 , PAG , false ) ;
BT_MBOX_PRINT ( 2 , INQUIRY , false ) ;
BT_MBOX_PRINT ( 2 , CONN , false ) ;
BT_MBOX_PRINT ( 2 , SNIFF_INTERVAL , false ) ;
BT_MBOX_PRINT ( 2 , DISC , false ) ;
BT_MBOX_PRINT ( 2 , SCO_TX_ACT , false ) ;
BT_MBOX_PRINT ( 2 , SCO_RX_ACT , false ) ;
BT_MBOX_PRINT ( 2 , ESCO_RE_TX , false ) ;
BT_MBOX_PRINT ( 2 , SCO_DURATION , true ) ;
pos + = scnprintf ( buf + pos , bufsz - pos , " MBOX dw3: \n " ) ;
BT_MBOX_PRINT ( 3 , SCO_STATE , false ) ;
BT_MBOX_PRINT ( 3 , SNIFF_STATE , false ) ;
BT_MBOX_PRINT ( 3 , A2DP_STATE , false ) ;
BT_MBOX_PRINT ( 3 , ACL_STATE , false ) ;
BT_MBOX_PRINT ( 3 , MSTR_STATE , false ) ;
BT_MBOX_PRINT ( 3 , OBX_STATE , false ) ;
BT_MBOX_PRINT ( 3 , OPEN_CON_2 , false ) ;
BT_MBOX_PRINT ( 3 , TRAFFIC_LOAD , false ) ;
BT_MBOX_PRINT ( 3 , CHL_SEQN_LSB , false ) ;
BT_MBOX_PRINT ( 3 , INBAND_P , false ) ;
BT_MBOX_PRINT ( 3 , MSG_TYPE_2 , false ) ;
BT_MBOX_PRINT ( 3 , SSN_2 , false ) ;
BT_MBOX_PRINT ( 3 , UPDATE_REQUEST , true ) ;
2014-07-02 17:33:52 +03:00
return pos ;
}
static ssize_t iwl_dbgfs_bt_notif_read ( struct file * file , char __user * user_buf ,
size_t count , loff_t * ppos )
{
struct iwl_mvm * mvm = file - > private_data ;
char * buf ;
int ret , pos = 0 , bufsz = sizeof ( char ) * 1024 ;
buf = kmalloc ( bufsz , GFP_KERNEL ) ;
if ( ! buf )
return - ENOMEM ;
mutex_lock ( & mvm - > mutex ) ;
if ( ! ( mvm - > fw - > ucode_capa . api [ 0 ] & IWL_UCODE_TLV_API_BT_COEX_SPLIT ) ) {
struct iwl_bt_coex_profile_notif_old * notif =
& mvm - > last_bt_notif_old ;
pos + = iwl_mvm_coex_dump_mbox_old ( notif , buf , pos , bufsz ) ;
pos + = scnprintf ( buf + pos , bufsz - pos , " bt_ci_compliance = %d \n " ,
notif - > bt_ci_compliance ) ;
pos + = scnprintf ( buf + pos , bufsz - pos , " primary_ch_lut = %d \n " ,
le32_to_cpu ( notif - > primary_ch_lut ) ) ;
pos + = scnprintf ( buf + pos , bufsz - pos , " secondary_ch_lut = %d \n " ,
le32_to_cpu ( notif - > secondary_ch_lut ) ) ;
pos + = scnprintf ( buf + pos ,
bufsz - pos , " bt_activity_grading = %d \n " ,
le32_to_cpu ( notif - > bt_activity_grading ) ) ;
pos + = scnprintf ( buf + pos , bufsz - pos ,
" antenna isolation = %d CORUN LUT index = %d \n " ,
mvm - > last_ant_isol , mvm - > last_corun_lut ) ;
} else {
struct iwl_bt_coex_profile_notif * notif =
& mvm - > last_bt_notif ;
pos + = iwl_mvm_coex_dump_mbox ( notif , buf , pos , bufsz ) ;
pos + = scnprintf ( buf + pos , bufsz - pos , " bt_ci_compliance = %d \n " ,
notif - > bt_ci_compliance ) ;
pos + = scnprintf ( buf + pos , bufsz - pos , " primary_ch_lut = %d \n " ,
le32_to_cpu ( notif - > primary_ch_lut ) ) ;
pos + = scnprintf ( buf + pos , bufsz - pos , " secondary_ch_lut = %d \n " ,
le32_to_cpu ( notif - > secondary_ch_lut ) ) ;
pos + = scnprintf ( buf + pos ,
bufsz - pos , " bt_activity_grading = %d \n " ,
le32_to_cpu ( notif - > bt_activity_grading ) ) ;
pos + = scnprintf ( buf + pos , bufsz - pos ,
" antenna isolation = %d CORUN LUT index = %d \n " ,
mvm - > last_ant_isol , mvm - > last_corun_lut ) ;
}
2013-02-19 11:02:36 +02:00
mutex_unlock ( & mvm - > mutex ) ;
ret = simple_read_from_buffer ( user_buf , count , ppos , buf , pos ) ;
kfree ( buf ) ;
return ret ;
}
# undef BT_MBOX_PRINT
2013-06-30 07:43:28 +03:00
static ssize_t iwl_dbgfs_bt_cmd_read ( struct file * file , char __user * user_buf ,
size_t count , loff_t * ppos )
{
struct iwl_mvm * mvm = file - > private_data ;
char buf [ 256 ] ;
int bufsz = sizeof ( buf ) ;
int pos = 0 ;
mutex_lock ( & mvm - > mutex ) ;
2014-07-02 17:33:52 +03:00
if ( ! ( mvm - > fw - > ucode_capa . api [ 0 ] & IWL_UCODE_TLV_API_BT_COEX_SPLIT ) ) {
struct iwl_bt_coex_ci_cmd_old * cmd = & mvm - > last_bt_ci_cmd_old ;
pos + = scnprintf ( buf + pos , bufsz - pos ,
" Channel inhibition CMD \n " ) ;
pos + = scnprintf ( buf + pos , bufsz - pos ,
" \t Primary Channel Bitmap 0x%016llx \n " ,
le64_to_cpu ( cmd - > bt_primary_ci ) ) ;
pos + = scnprintf ( buf + pos , bufsz - pos ,
" \t Secondary Channel Bitmap 0x%016llx \n " ,
le64_to_cpu ( cmd - > bt_secondary_ci ) ) ;
pos + = scnprintf ( buf + pos , bufsz - pos , " BT Configuration CMD \n " ) ;
pos + = scnprintf ( buf + pos , bufsz - pos , " \t ACK Kill Mask 0x%08x \n " ,
2014-07-06 09:34:38 +03:00
iwl_bt_ctl_kill_msk [ mvm - > bt_ack_kill_msk [ 0 ] ] ) ;
2014-07-02 17:33:52 +03:00
pos + = scnprintf ( buf + pos , bufsz - pos , " \t CTS Kill Mask 0x%08x \n " ,
2014-07-06 09:34:38 +03:00
iwl_bt_ctl_kill_msk [ mvm - > bt_cts_kill_msk [ 0 ] ] ) ;
2014-07-02 17:33:52 +03:00
} else {
struct iwl_bt_coex_ci_cmd * cmd = & mvm - > last_bt_ci_cmd ;
pos + = scnprintf ( buf + pos , bufsz - pos ,
" Channel inhibition CMD \n " ) ;
pos + = scnprintf ( buf + pos , bufsz - pos ,
" \t Primary Channel Bitmap 0x%016llx \n " ,
le64_to_cpu ( cmd - > bt_primary_ci ) ) ;
pos + = scnprintf ( buf + pos , bufsz - pos ,
" \t Secondary Channel Bitmap 0x%016llx \n " ,
le64_to_cpu ( cmd - > bt_secondary_ci ) ) ;
pos + = scnprintf ( buf + pos , bufsz - pos , " BT Configuration CMD \n " ) ;
2014-07-06 09:34:38 +03:00
pos + = scnprintf ( buf + pos , bufsz - pos ,
" \t Primary: ACK Kill Mask 0x%08x \n " ,
iwl_bt_ctl_kill_msk [ mvm - > bt_ack_kill_msk [ 0 ] ] ) ;
pos + = scnprintf ( buf + pos , bufsz - pos ,
" \t Primary: CTS Kill Mask 0x%08x \n " ,
iwl_bt_ctl_kill_msk [ mvm - > bt_cts_kill_msk [ 0 ] ] ) ;
pos + = scnprintf ( buf + pos , bufsz - pos ,
" \t Secondary: ACK Kill Mask 0x%08x \n " ,
iwl_bt_ctl_kill_msk [ mvm - > bt_ack_kill_msk [ 1 ] ] ) ;
pos + = scnprintf ( buf + pos , bufsz - pos ,
" \t Secondary: CTS Kill Mask 0x%08x \n " ,
iwl_bt_ctl_kill_msk [ mvm - > bt_cts_kill_msk [ 1 ] ] ) ;
2014-07-02 17:33:52 +03:00
}
2013-06-30 07:43:28 +03:00
mutex_unlock ( & mvm - > mutex ) ;
return simple_read_from_buffer ( user_buf , count , ppos , buf , pos ) ;
}
2014-03-16 21:55:43 +02:00
static ssize_t
iwl_dbgfs_bt_tx_prio_write ( struct iwl_mvm * mvm , char * buf ,
size_t count , loff_t * ppos )
{
u32 bt_tx_prio ;
if ( sscanf ( buf , " %u " , & bt_tx_prio ) ! = 1 )
return - EINVAL ;
if ( bt_tx_prio > 4 )
return - EINVAL ;
mvm - > bt_tx_prio = bt_tx_prio ;
return count ;
}
2014-05-28 12:06:41 +03:00
static ssize_t
iwl_dbgfs_bt_force_ant_write ( struct iwl_mvm * mvm , char * buf ,
size_t count , loff_t * ppos )
{
static const char * const modes_str [ BT_FORCE_ANT_MAX ] = {
[ BT_FORCE_ANT_DIS ] = " dis " ,
[ BT_FORCE_ANT_AUTO ] = " auto " ,
[ BT_FORCE_ANT_BT ] = " bt " ,
[ BT_FORCE_ANT_WIFI ] = " wifi " ,
} ;
int ret , bt_force_ant_mode ;
for ( bt_force_ant_mode = 0 ;
bt_force_ant_mode < ARRAY_SIZE ( modes_str ) ;
bt_force_ant_mode + + ) {
if ( ! strcmp ( buf , modes_str [ bt_force_ant_mode ] ) )
break ;
}
if ( bt_force_ant_mode > = ARRAY_SIZE ( modes_str ) )
return - EINVAL ;
ret = 0 ;
mutex_lock ( & mvm - > mutex ) ;
if ( mvm - > bt_force_ant_mode = = bt_force_ant_mode )
goto out ;
mvm - > bt_force_ant_mode = bt_force_ant_mode ;
IWL_DEBUG_COEX ( mvm , " Force mode: %s \n " ,
modes_str [ mvm - > bt_force_ant_mode ] ) ;
ret = iwl_send_bt_init_conf ( mvm ) ;
out :
mutex_unlock ( & mvm - > mutex ) ;
return ret ? : count ;
}
2013-07-30 15:29:37 +03:00
# define PRINT_STATS_LE32(_str, _val) \
pos + = scnprintf ( buf + pos , bufsz - pos , \
fmt_table , _str , \
le32_to_cpu ( _val ) )
static ssize_t iwl_dbgfs_fw_rx_stats_read ( struct file * file ,
char __user * user_buf , size_t count ,
loff_t * ppos )
{
struct iwl_mvm * mvm = file - > private_data ;
static const char * fmt_table = " \t %-30s %10u \n " ;
static const char * fmt_header = " %-32s \n " ;
int pos = 0 ;
char * buf ;
int ret ;
2013-10-14 13:18:41 +03:00
/* 43 is the size of each data line, 33 is the size of each header */
size_t bufsz =
( ( sizeof ( struct mvm_statistics_rx ) / sizeof ( __le32 ) ) * 43 ) +
( 4 * 33 ) + 1 ;
2013-07-30 15:29:37 +03:00
struct mvm_statistics_rx_phy * ofdm ;
struct mvm_statistics_rx_phy * cck ;
struct mvm_statistics_rx_non_phy * general ;
struct mvm_statistics_rx_ht_phy * ht ;
buf = kzalloc ( bufsz , GFP_KERNEL ) ;
if ( ! buf )
return - ENOMEM ;
mutex_lock ( & mvm - > mutex ) ;
ofdm = & mvm - > rx_stats . ofdm ;
cck = & mvm - > rx_stats . cck ;
general = & mvm - > rx_stats . general ;
ht = & mvm - > rx_stats . ofdm_ht ;
pos + = scnprintf ( buf + pos , bufsz - pos , fmt_header ,
" Statistics_Rx - OFDM " ) ;
PRINT_STATS_LE32 ( " ina_cnt " , ofdm - > ina_cnt ) ;
PRINT_STATS_LE32 ( " fina_cnt " , ofdm - > fina_cnt ) ;
PRINT_STATS_LE32 ( " plcp_err " , ofdm - > plcp_err ) ;
PRINT_STATS_LE32 ( " crc32_err " , ofdm - > crc32_err ) ;
PRINT_STATS_LE32 ( " overrun_err " , ofdm - > overrun_err ) ;
PRINT_STATS_LE32 ( " early_overrun_err " , ofdm - > early_overrun_err ) ;
PRINT_STATS_LE32 ( " crc32_good " , ofdm - > crc32_good ) ;
PRINT_STATS_LE32 ( " false_alarm_cnt " , ofdm - > false_alarm_cnt ) ;
PRINT_STATS_LE32 ( " fina_sync_err_cnt " , ofdm - > fina_sync_err_cnt ) ;
PRINT_STATS_LE32 ( " sfd_timeout " , ofdm - > sfd_timeout ) ;
PRINT_STATS_LE32 ( " fina_timeout " , ofdm - > fina_timeout ) ;
PRINT_STATS_LE32 ( " unresponded_rts " , ofdm - > unresponded_rts ) ;
PRINT_STATS_LE32 ( " rxe_frame_lmt_overrun " ,
ofdm - > rxe_frame_limit_overrun ) ;
PRINT_STATS_LE32 ( " sent_ack_cnt " , ofdm - > sent_ack_cnt ) ;
PRINT_STATS_LE32 ( " sent_cts_cnt " , ofdm - > sent_cts_cnt ) ;
PRINT_STATS_LE32 ( " sent_ba_rsp_cnt " , ofdm - > sent_ba_rsp_cnt ) ;
PRINT_STATS_LE32 ( " dsp_self_kill " , ofdm - > dsp_self_kill ) ;
PRINT_STATS_LE32 ( " mh_format_err " , ofdm - > mh_format_err ) ;
PRINT_STATS_LE32 ( " re_acq_main_rssi_sum " , ofdm - > re_acq_main_rssi_sum ) ;
PRINT_STATS_LE32 ( " reserved " , ofdm - > reserved ) ;
pos + = scnprintf ( buf + pos , bufsz - pos , fmt_header ,
" Statistics_Rx - CCK " ) ;
PRINT_STATS_LE32 ( " ina_cnt " , cck - > ina_cnt ) ;
PRINT_STATS_LE32 ( " fina_cnt " , cck - > fina_cnt ) ;
PRINT_STATS_LE32 ( " plcp_err " , cck - > plcp_err ) ;
PRINT_STATS_LE32 ( " crc32_err " , cck - > crc32_err ) ;
PRINT_STATS_LE32 ( " overrun_err " , cck - > overrun_err ) ;
PRINT_STATS_LE32 ( " early_overrun_err " , cck - > early_overrun_err ) ;
PRINT_STATS_LE32 ( " crc32_good " , cck - > crc32_good ) ;
PRINT_STATS_LE32 ( " false_alarm_cnt " , cck - > false_alarm_cnt ) ;
PRINT_STATS_LE32 ( " fina_sync_err_cnt " , cck - > fina_sync_err_cnt ) ;
PRINT_STATS_LE32 ( " sfd_timeout " , cck - > sfd_timeout ) ;
PRINT_STATS_LE32 ( " fina_timeout " , cck - > fina_timeout ) ;
PRINT_STATS_LE32 ( " unresponded_rts " , cck - > unresponded_rts ) ;
PRINT_STATS_LE32 ( " rxe_frame_lmt_overrun " ,
cck - > rxe_frame_limit_overrun ) ;
PRINT_STATS_LE32 ( " sent_ack_cnt " , cck - > sent_ack_cnt ) ;
PRINT_STATS_LE32 ( " sent_cts_cnt " , cck - > sent_cts_cnt ) ;
PRINT_STATS_LE32 ( " sent_ba_rsp_cnt " , cck - > sent_ba_rsp_cnt ) ;
PRINT_STATS_LE32 ( " dsp_self_kill " , cck - > dsp_self_kill ) ;
PRINT_STATS_LE32 ( " mh_format_err " , cck - > mh_format_err ) ;
PRINT_STATS_LE32 ( " re_acq_main_rssi_sum " , cck - > re_acq_main_rssi_sum ) ;
PRINT_STATS_LE32 ( " reserved " , cck - > reserved ) ;
pos + = scnprintf ( buf + pos , bufsz - pos , fmt_header ,
" Statistics_Rx - GENERAL " ) ;
PRINT_STATS_LE32 ( " bogus_cts " , general - > bogus_cts ) ;
PRINT_STATS_LE32 ( " bogus_ack " , general - > bogus_ack ) ;
PRINT_STATS_LE32 ( " non_bssid_frames " , general - > non_bssid_frames ) ;
PRINT_STATS_LE32 ( " filtered_frames " , general - > filtered_frames ) ;
PRINT_STATS_LE32 ( " non_channel_beacons " , general - > non_channel_beacons ) ;
PRINT_STATS_LE32 ( " channel_beacons " , general - > channel_beacons ) ;
PRINT_STATS_LE32 ( " num_missed_bcon " , general - > num_missed_bcon ) ;
PRINT_STATS_LE32 ( " adc_rx_saturation_time " ,
general - > adc_rx_saturation_time ) ;
PRINT_STATS_LE32 ( " ina_detection_search_time " ,
general - > ina_detection_search_time ) ;
PRINT_STATS_LE32 ( " beacon_silence_rssi_a " ,
general - > beacon_silence_rssi_a ) ;
PRINT_STATS_LE32 ( " beacon_silence_rssi_b " ,
general - > beacon_silence_rssi_b ) ;
PRINT_STATS_LE32 ( " beacon_silence_rssi_c " ,
general - > beacon_silence_rssi_c ) ;
PRINT_STATS_LE32 ( " interference_data_flag " ,
general - > interference_data_flag ) ;
PRINT_STATS_LE32 ( " channel_load " , general - > channel_load ) ;
PRINT_STATS_LE32 ( " dsp_false_alarms " , general - > dsp_false_alarms ) ;
PRINT_STATS_LE32 ( " beacon_rssi_a " , general - > beacon_rssi_a ) ;
PRINT_STATS_LE32 ( " beacon_rssi_b " , general - > beacon_rssi_b ) ;
PRINT_STATS_LE32 ( " beacon_rssi_c " , general - > beacon_rssi_c ) ;
PRINT_STATS_LE32 ( " beacon_energy_a " , general - > beacon_energy_a ) ;
PRINT_STATS_LE32 ( " beacon_energy_b " , general - > beacon_energy_b ) ;
PRINT_STATS_LE32 ( " beacon_energy_c " , general - > beacon_energy_c ) ;
PRINT_STATS_LE32 ( " num_bt_kills " , general - > num_bt_kills ) ;
2013-10-14 13:18:41 +03:00
PRINT_STATS_LE32 ( " mac_id " , general - > mac_id ) ;
2013-07-30 15:29:37 +03:00
PRINT_STATS_LE32 ( " directed_data_mpdu " , general - > directed_data_mpdu ) ;
pos + = scnprintf ( buf + pos , bufsz - pos , fmt_header ,
" Statistics_Rx - HT " ) ;
PRINT_STATS_LE32 ( " plcp_err " , ht - > plcp_err ) ;
PRINT_STATS_LE32 ( " overrun_err " , ht - > overrun_err ) ;
PRINT_STATS_LE32 ( " early_overrun_err " , ht - > early_overrun_err ) ;
PRINT_STATS_LE32 ( " crc32_good " , ht - > crc32_good ) ;
PRINT_STATS_LE32 ( " crc32_err " , ht - > crc32_err ) ;
PRINT_STATS_LE32 ( " mh_format_err " , ht - > mh_format_err ) ;
PRINT_STATS_LE32 ( " agg_crc32_good " , ht - > agg_crc32_good ) ;
PRINT_STATS_LE32 ( " agg_mpdu_cnt " , ht - > agg_mpdu_cnt ) ;
PRINT_STATS_LE32 ( " agg_cnt " , ht - > agg_cnt ) ;
PRINT_STATS_LE32 ( " unsupport_mcs " , ht - > unsupport_mcs ) ;
mutex_unlock ( & mvm - > mutex ) ;
ret = simple_read_from_buffer ( user_buf , count , ppos , buf , pos ) ;
kfree ( buf ) ;
return ret ;
}
# undef PRINT_STAT_LE32
2014-01-28 01:35:32 +02:00
static ssize_t iwl_dbgfs_frame_stats_read ( struct iwl_mvm * mvm ,
char __user * user_buf , size_t count ,
loff_t * ppos ,
struct iwl_mvm_frame_stats * stats )
{
2014-02-24 10:24:34 +02:00
char * buff , * pos , * endpos ;
int idx , i ;
2014-01-28 01:35:32 +02:00
int ret ;
2014-02-24 10:24:34 +02:00
static const size_t bufsz = 1024 ;
2014-01-28 01:35:32 +02:00
buff = kmalloc ( bufsz , GFP_KERNEL ) ;
if ( ! buff )
return - ENOMEM ;
spin_lock_bh ( & mvm - > drv_stats_lock ) ;
2014-02-24 10:24:34 +02:00
pos = buff ;
endpos = pos + bufsz ;
pos + = scnprintf ( pos , endpos - pos ,
2014-01-28 01:35:32 +02:00
" Legacy/HT/VHT \t : \t %d/%d/%d \n " ,
stats - > legacy_frames ,
stats - > ht_frames ,
stats - > vht_frames ) ;
2014-02-24 10:24:34 +02:00
pos + = scnprintf ( pos , endpos - pos , " 20/40/80 \t : \t %d/%d/%d \n " ,
2014-01-28 01:35:32 +02:00
stats - > bw_20_frames ,
stats - > bw_40_frames ,
stats - > bw_80_frames ) ;
2014-02-24 10:24:34 +02:00
pos + = scnprintf ( pos , endpos - pos , " NGI/SGI \t \t : \t %d/%d \n " ,
2014-01-28 01:35:32 +02:00
stats - > ngi_frames ,
stats - > sgi_frames ) ;
2014-02-24 10:24:34 +02:00
pos + = scnprintf ( pos , endpos - pos , " SISO/MIMO2 \t : \t %d/%d \n " ,
2014-01-28 01:35:32 +02:00
stats - > siso_frames ,
stats - > mimo2_frames ) ;
2014-02-24 10:24:34 +02:00
pos + = scnprintf ( pos , endpos - pos , " FAIL/SCSS \t : \t %d/%d \n " ,
2014-01-28 01:35:32 +02:00
stats - > fail_frames ,
stats - > success_frames ) ;
2014-02-24 10:24:34 +02:00
pos + = scnprintf ( pos , endpos - pos , " MPDUs agg \t : \t %d \n " ,
2014-01-28 01:35:32 +02:00
stats - > agg_frames ) ;
2014-02-24 10:24:34 +02:00
pos + = scnprintf ( pos , endpos - pos , " A-MPDUs \t \t : \t %d \n " ,
2014-01-28 01:35:32 +02:00
stats - > ampdu_count ) ;
2014-02-24 10:24:34 +02:00
pos + = scnprintf ( pos , endpos - pos , " Avg MPDUs/A-MPDU: \t %d \n " ,
2014-01-28 01:35:32 +02:00
stats - > ampdu_count > 0 ?
( stats - > agg_frames / stats - > ampdu_count ) : 0 ) ;
2014-02-24 10:24:34 +02:00
pos + = scnprintf ( pos , endpos - pos , " Last Rates \n " ) ;
2014-01-28 01:35:32 +02:00
idx = stats - > last_frame_idx - 1 ;
for ( i = 0 ; i < ARRAY_SIZE ( stats - > last_rates ) ; i + + ) {
idx = ( idx + 1 ) % ARRAY_SIZE ( stats - > last_rates ) ;
if ( stats - > last_rates [ idx ] = = 0 )
continue ;
2014-02-24 10:24:34 +02:00
pos + = scnprintf ( pos , endpos - pos , " Rate[%d]: " ,
2014-01-28 01:35:32 +02:00
( int ) ( ARRAY_SIZE ( stats - > last_rates ) - i ) ) ;
2014-02-24 10:24:34 +02:00
pos + = rs_pretty_print_rate ( pos , stats - > last_rates [ idx ] ) ;
2014-01-28 01:35:32 +02:00
}
spin_unlock_bh ( & mvm - > drv_stats_lock ) ;
2014-02-24 10:24:34 +02:00
ret = simple_read_from_buffer ( user_buf , count , ppos , buff , pos - buff ) ;
2014-01-28 01:35:32 +02:00
kfree ( buff ) ;
return ret ;
}
static ssize_t iwl_dbgfs_drv_rx_stats_read ( struct file * file ,
char __user * user_buf , size_t count ,
loff_t * ppos )
{
struct iwl_mvm * mvm = file - > private_data ;
return iwl_dbgfs_frame_stats_read ( mvm , user_buf , count , ppos ,
& mvm - > drv_rx_stats ) ;
}
2013-11-13 09:10:21 +01:00
static ssize_t iwl_dbgfs_fw_restart_write ( struct iwl_mvm * mvm , char * buf ,
2013-03-04 08:53:07 +02:00
size_t count , loff_t * ppos )
{
int ret ;
mutex_lock ( & mvm - > mutex ) ;
2013-07-03 11:00:06 +03:00
/* allow one more restart that we're provoking here */
if ( mvm - > restart_fw > = 0 )
mvm - > restart_fw + + ;
2013-03-04 08:53:07 +02:00
/* take the return value to make compiler happy - it will fail anyway */
2014-05-12 11:36:41 +03:00
ret = iwl_mvm_send_cmd_pdu ( mvm , REPLY_ERROR , 0 , 0 , NULL ) ;
2013-03-04 08:53:07 +02:00
mutex_unlock ( & mvm - > mutex ) ;
return count ;
}
2013-11-13 09:10:21 +01:00
static ssize_t iwl_dbgfs_fw_nmi_write ( struct iwl_mvm * mvm , char * buf ,
2013-10-17 14:26:50 +02:00
size_t count , loff_t * ppos )
{
2014-07-01 18:38:38 +03:00
int ret = iwl_mvm_ref_sync ( mvm , IWL_MVM_REF_NMI ) ;
if ( ret )
return ret ;
2014-04-27 16:46:09 +03:00
iwl_force_nmi ( mvm - > trans ) ;
2013-10-17 14:26:50 +02:00
2014-07-01 18:38:38 +03:00
iwl_mvm_unref ( mvm , IWL_MVM_REF_NMI ) ;
2013-10-17 14:26:50 +02:00
return count ;
}
2013-08-19 08:36:48 +03:00
static ssize_t
iwl_dbgfs_scan_ant_rxchain_read ( struct file * file ,
char __user * user_buf ,
size_t count , loff_t * ppos )
{
struct iwl_mvm * mvm = file - > private_data ;
int pos = 0 ;
char buf [ 32 ] ;
const size_t bufsz = sizeof ( buf ) ;
/* print which antennas were set for the scan command by the user */
pos + = scnprintf ( buf + pos , bufsz - pos , " Antennas for scan: " ) ;
if ( mvm - > scan_rx_ant & ANT_A )
pos + = scnprintf ( buf + pos , bufsz - pos , " A " ) ;
if ( mvm - > scan_rx_ant & ANT_B )
pos + = scnprintf ( buf + pos , bufsz - pos , " B " ) ;
if ( mvm - > scan_rx_ant & ANT_C )
pos + = scnprintf ( buf + pos , bufsz - pos , " C " ) ;
pos + = scnprintf ( buf + pos , bufsz - pos , " (%hhx) \n " , mvm - > scan_rx_ant ) ;
return simple_read_from_buffer ( user_buf , count , ppos , buf , pos ) ;
}
static ssize_t
2013-11-13 09:10:21 +01:00
iwl_dbgfs_scan_ant_rxchain_write ( struct iwl_mvm * mvm , char * buf ,
2013-08-19 08:36:48 +03:00
size_t count , loff_t * ppos )
{
u8 scan_rx_ant ;
if ( sscanf ( buf , " %hhx " , & scan_rx_ant ) ! = 1 )
return - EINVAL ;
if ( scan_rx_ant > ANT_ABC )
return - EINVAL ;
2014-02-12 21:47:44 +01:00
if ( scan_rx_ant & ~ mvm - > fw - > valid_rx_ant )
2013-08-19 08:36:48 +03:00
return - EINVAL ;
mvm - > scan_rx_ant = scan_rx_ant ;
return count ;
}
2014-01-08 10:11:12 +02:00
# define ADD_TEXT(...) pos += scnprintf(buf + pos, bufsz - pos, __VA_ARGS__)
# ifdef CONFIG_IWLWIFI_BCAST_FILTERING
static ssize_t iwl_dbgfs_bcast_filters_read ( struct file * file ,
char __user * user_buf ,
size_t count , loff_t * ppos )
{
struct iwl_mvm * mvm = file - > private_data ;
struct iwl_bcast_filter_cmd cmd ;
const struct iwl_fw_bcast_filter * filter ;
char * buf ;
int bufsz = 1024 ;
int i , j , pos = 0 ;
ssize_t ret ;
buf = kzalloc ( bufsz , GFP_KERNEL ) ;
if ( ! buf )
return - ENOMEM ;
mutex_lock ( & mvm - > mutex ) ;
if ( ! iwl_mvm_bcast_filter_build_cmd ( mvm , & cmd ) ) {
ADD_TEXT ( " None \n " ) ;
mutex_unlock ( & mvm - > mutex ) ;
goto out ;
}
mutex_unlock ( & mvm - > mutex ) ;
for ( i = 0 ; cmd . filters [ i ] . attrs [ 0 ] . mask ; i + + ) {
filter = & cmd . filters [ i ] ;
ADD_TEXT ( " Filter [%d]: \n " , i ) ;
ADD_TEXT ( " \t Discard=%d \n " , filter - > discard ) ;
ADD_TEXT ( " \t Frame Type: %s \n " ,
filter - > frame_type ? " IPv4 " : " Generic " ) ;
for ( j = 0 ; j < ARRAY_SIZE ( filter - > attrs ) ; j + + ) {
const struct iwl_fw_bcast_filter_attr * attr ;
attr = & filter - > attrs [ j ] ;
if ( ! attr - > mask )
break ;
ADD_TEXT ( " \t Attr [%d]: offset=%d (from %s), mask=0x%x, value=0x%x reserved=0x%x \n " ,
j , attr - > offset ,
attr - > offset_type ? " IP End " :
" Payload Start " ,
be32_to_cpu ( attr - > mask ) ,
be32_to_cpu ( attr - > val ) ,
le16_to_cpu ( attr - > reserved1 ) ) ;
}
}
out :
ret = simple_read_from_buffer ( user_buf , count , ppos , buf , pos ) ;
kfree ( buf ) ;
return ret ;
}
static ssize_t iwl_dbgfs_bcast_filters_write ( struct iwl_mvm * mvm , char * buf ,
size_t count , loff_t * ppos )
{
int pos , next_pos ;
struct iwl_fw_bcast_filter filter = { } ;
struct iwl_bcast_filter_cmd cmd ;
u32 filter_id , attr_id , mask , value ;
int err = 0 ;
if ( sscanf ( buf , " %d %hhi %hhi %n " , & filter_id , & filter . discard ,
& filter . frame_type , & pos ) ! = 3 )
return - EINVAL ;
if ( filter_id > = ARRAY_SIZE ( mvm - > dbgfs_bcast_filtering . cmd . filters ) | |
filter . frame_type > BCAST_FILTER_FRAME_TYPE_IPV4 )
return - EINVAL ;
for ( attr_id = 0 ; attr_id < ARRAY_SIZE ( filter . attrs ) ;
attr_id + + ) {
struct iwl_fw_bcast_filter_attr * attr =
& filter . attrs [ attr_id ] ;
if ( pos > = count )
break ;
if ( sscanf ( & buf [ pos ] , " %hhi %hhi %i %i %n " ,
& attr - > offset , & attr - > offset_type ,
& mask , & value , & next_pos ) ! = 4 )
return - EINVAL ;
attr - > mask = cpu_to_be32 ( mask ) ;
attr - > val = cpu_to_be32 ( value ) ;
if ( mask )
filter . num_attrs + + ;
pos + = next_pos ;
}
mutex_lock ( & mvm - > mutex ) ;
memcpy ( & mvm - > dbgfs_bcast_filtering . cmd . filters [ filter_id ] ,
& filter , sizeof ( filter ) ) ;
/* send updated bcast filtering configuration */
if ( mvm - > dbgfs_bcast_filtering . override & &
iwl_mvm_bcast_filter_build_cmd ( mvm , & cmd ) )
2014-05-12 11:36:41 +03:00
err = iwl_mvm_send_cmd_pdu ( mvm , BCAST_FILTER_CMD , 0 ,
2014-01-08 10:11:12 +02:00
sizeof ( cmd ) , & cmd ) ;
mutex_unlock ( & mvm - > mutex ) ;
return err ? : count ;
}
static ssize_t iwl_dbgfs_bcast_filters_macs_read ( struct file * file ,
char __user * user_buf ,
size_t count , loff_t * ppos )
{
struct iwl_mvm * mvm = file - > private_data ;
struct iwl_bcast_filter_cmd cmd ;
char * buf ;
int bufsz = 1024 ;
int i , pos = 0 ;
ssize_t ret ;
buf = kzalloc ( bufsz , GFP_KERNEL ) ;
if ( ! buf )
return - ENOMEM ;
mutex_lock ( & mvm - > mutex ) ;
if ( ! iwl_mvm_bcast_filter_build_cmd ( mvm , & cmd ) ) {
ADD_TEXT ( " None \n " ) ;
mutex_unlock ( & mvm - > mutex ) ;
goto out ;
}
mutex_unlock ( & mvm - > mutex ) ;
for ( i = 0 ; i < ARRAY_SIZE ( cmd . macs ) ; i + + ) {
const struct iwl_fw_bcast_mac * mac = & cmd . macs [ i ] ;
ADD_TEXT ( " Mac [%d]: discard=%d attached_filters=0x%x \n " ,
i , mac - > default_discard , mac - > attached_filters ) ;
}
out :
ret = simple_read_from_buffer ( user_buf , count , ppos , buf , pos ) ;
kfree ( buf ) ;
return ret ;
}
static ssize_t iwl_dbgfs_bcast_filters_macs_write ( struct iwl_mvm * mvm ,
char * buf , size_t count ,
loff_t * ppos )
{
struct iwl_bcast_filter_cmd cmd ;
struct iwl_fw_bcast_mac mac = { } ;
u32 mac_id , attached_filters ;
int err = 0 ;
if ( ! mvm - > bcast_filters )
return - ENOENT ;
if ( sscanf ( buf , " %d %hhi %i " , & mac_id , & mac . default_discard ,
& attached_filters ) ! = 3 )
return - EINVAL ;
if ( mac_id > = ARRAY_SIZE ( cmd . macs ) | |
mac . default_discard > 1 | |
attached_filters > = BIT ( ARRAY_SIZE ( cmd . filters ) ) )
return - EINVAL ;
mac . attached_filters = cpu_to_le16 ( attached_filters ) ;
mutex_lock ( & mvm - > mutex ) ;
memcpy ( & mvm - > dbgfs_bcast_filtering . cmd . macs [ mac_id ] ,
& mac , sizeof ( mac ) ) ;
/* send updated bcast filtering configuration */
if ( mvm - > dbgfs_bcast_filtering . override & &
iwl_mvm_bcast_filter_build_cmd ( mvm , & cmd ) )
2014-05-12 11:36:41 +03:00
err = iwl_mvm_send_cmd_pdu ( mvm , BCAST_FILTER_CMD , 0 ,
2014-01-08 10:11:12 +02:00
sizeof ( cmd ) , & cmd ) ;
mutex_unlock ( & mvm - > mutex ) ;
return err ? : count ;
}
# endif
2013-05-03 11:44:16 +02:00
# ifdef CONFIG_PM_SLEEP
2013-11-13 09:10:21 +01:00
static ssize_t iwl_dbgfs_d3_sram_write ( struct iwl_mvm * mvm , char * buf ,
2013-05-03 11:44:16 +02:00
size_t count , loff_t * ppos )
{
int store ;
if ( sscanf ( buf , " %d " , & store ) ! = 1 )
return - EINVAL ;
mvm - > store_d3_resume_sram = store ;
return count ;
}
static ssize_t iwl_dbgfs_d3_sram_read ( struct file * file , char __user * user_buf ,
size_t count , loff_t * ppos )
{
struct iwl_mvm * mvm = file - > private_data ;
const struct fw_img * img ;
int ofs , len , pos = 0 ;
size_t bufsz , ret ;
char * buf ;
u8 * ptr = mvm - > d3_resume_sram ;
img = & mvm - > fw - > img [ IWL_UCODE_WOWLAN ] ;
len = img - > sec [ IWL_UCODE_SECTION_DATA ] . len ;
bufsz = len * 4 + 256 ;
buf = kzalloc ( bufsz , GFP_KERNEL ) ;
if ( ! buf )
return - ENOMEM ;
pos + = scnprintf ( buf , bufsz , " D3 SRAM capture: %sabled \n " ,
mvm - > store_d3_resume_sram ? " en " : " dis " ) ;
if ( ptr ) {
for ( ofs = 0 ; ofs < len ; ofs + = 16 ) {
pos + = scnprintf ( buf + pos , bufsz - pos ,
" 0x%.4x " , ofs ) ;
hex_dump_to_buffer ( ptr + ofs , 16 , 16 , 1 , buf + pos ,
bufsz - pos , false ) ;
pos + = strlen ( buf + pos ) ;
if ( bufsz - pos > 0 )
buf [ pos + + ] = ' \n ' ;
}
} else {
pos + = scnprintf ( buf + pos , bufsz - pos ,
" (no data captured) \n " ) ;
}
ret = simple_read_from_buffer ( user_buf , count , ppos , buf , pos ) ;
kfree ( buf ) ;
return ret ;
}
# endif
2014-07-01 18:38:38 +03:00
# define PRINT_MVM_REF(ref) do { \
if ( mvm - > refs [ ref ] ) \
pos + = scnprintf ( buf + pos , bufsz - pos , \
" \t (0x%lx): %d %s \n " , \
BIT ( ref ) , mvm - > refs [ ref ] , # ref ) ; \
2013-11-05 14:45:16 +02:00
} while ( 0 )
static ssize_t iwl_dbgfs_d0i3_refs_read ( struct file * file ,
char __user * user_buf ,
size_t count , loff_t * ppos )
{
struct iwl_mvm * mvm = file - > private_data ;
2014-07-01 18:38:38 +03:00
int i , pos = 0 ;
2013-11-05 14:45:16 +02:00
char buf [ 256 ] ;
const size_t bufsz = sizeof ( buf ) ;
2014-07-01 18:38:38 +03:00
u32 refs = 0 ;
for ( i = 0 ; i < IWL_MVM_REF_COUNT ; i + + )
if ( mvm - > refs [ i ] )
refs | = BIT ( i ) ;
2013-11-05 14:45:16 +02:00
2014-07-01 18:38:38 +03:00
pos + = scnprintf ( buf + pos , bufsz - pos , " taken mvm refs: 0x%x \n " ,
refs ) ;
2013-11-05 14:45:16 +02:00
PRINT_MVM_REF ( IWL_MVM_REF_UCODE_DOWN ) ;
PRINT_MVM_REF ( IWL_MVM_REF_SCAN ) ;
PRINT_MVM_REF ( IWL_MVM_REF_ROC ) ;
PRINT_MVM_REF ( IWL_MVM_REF_P2P_CLIENT ) ;
PRINT_MVM_REF ( IWL_MVM_REF_AP_IBSS ) ;
2013-11-11 18:56:35 +02:00
PRINT_MVM_REF ( IWL_MVM_REF_USER ) ;
2014-03-27 18:53:12 +02:00
PRINT_MVM_REF ( IWL_MVM_REF_EXIT_WORK ) ;
2013-11-05 14:45:16 +02:00
return simple_read_from_buffer ( user_buf , count , ppos , buf , pos ) ;
}
2013-11-11 18:56:35 +02:00
static ssize_t iwl_dbgfs_d0i3_refs_write ( struct iwl_mvm * mvm , char * buf ,
size_t count , loff_t * ppos )
{
unsigned long value ;
int ret ;
bool taken ;
ret = kstrtoul ( buf , 10 , & value ) ;
if ( ret < 0 )
return ret ;
mutex_lock ( & mvm - > mutex ) ;
2014-07-01 18:38:38 +03:00
taken = mvm - > refs [ IWL_MVM_REF_USER ] ;
2013-11-11 18:56:35 +02:00
if ( value = = 1 & & ! taken )
iwl_mvm_ref ( mvm , IWL_MVM_REF_USER ) ;
else if ( value = = 0 & & taken )
iwl_mvm_unref ( mvm , IWL_MVM_REF_USER ) ;
else
ret = - EINVAL ;
mutex_unlock ( & mvm - > mutex ) ;
if ( ret < 0 )
return ret ;
return count ;
}
2013-11-13 09:10:21 +01:00
# define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
_MVM_DEBUGFS_WRITE_FILE_OPS ( name , bufsz , struct iwl_mvm )
# define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
_MVM_DEBUGFS_READ_WRITE_FILE_OPS ( name , bufsz , struct iwl_mvm )
2014-01-08 10:11:12 +02:00
# define MVM_DEBUGFS_ADD_FILE_ALIAS(alias, name, parent, mode) do { \
if ( ! debugfs_create_file ( alias , mode , parent , mvm , \
2013-01-24 14:25:36 +01:00
& iwl_dbgfs_ # # name # # _ops ) ) \
goto err ; \
} while ( 0 )
2014-01-08 10:11:12 +02:00
# define MVM_DEBUGFS_ADD_FILE(name, parent, mode) \
MVM_DEBUGFS_ADD_FILE_ALIAS ( # name , name , parent , mode )
2013-01-24 14:25:36 +01:00
2014-01-09 13:12:54 +02:00
static ssize_t
iwl_dbgfs_prph_reg_read ( struct file * file ,
char __user * user_buf ,
size_t count , loff_t * ppos )
{
struct iwl_mvm * mvm = file - > private_data ;
int pos = 0 ;
char buf [ 32 ] ;
const size_t bufsz = sizeof ( buf ) ;
2014-07-01 18:38:38 +03:00
int ret ;
2014-01-09 13:12:54 +02:00
if ( ! mvm - > dbgfs_prph_reg_addr )
return - EINVAL ;
2014-07-01 18:38:38 +03:00
ret = iwl_mvm_ref_sync ( mvm , IWL_MVM_REF_PRPH_READ ) ;
if ( ret )
return ret ;
2014-01-09 13:12:54 +02:00
pos + = scnprintf ( buf + pos , bufsz - pos , " Reg 0x%x: (0x%x) \n " ,
mvm - > dbgfs_prph_reg_addr ,
iwl_read_prph ( mvm - > trans , mvm - > dbgfs_prph_reg_addr ) ) ;
2014-07-01 18:38:38 +03:00
iwl_mvm_unref ( mvm , IWL_MVM_REF_PRPH_READ ) ;
2014-01-09 13:12:54 +02:00
return simple_read_from_buffer ( user_buf , count , ppos , buf , pos ) ;
}
static ssize_t
iwl_dbgfs_prph_reg_write ( struct iwl_mvm * mvm , char * buf ,
size_t count , loff_t * ppos )
{
u8 args ;
u32 value ;
2014-07-01 18:38:38 +03:00
int ret ;
2014-01-09 13:12:54 +02:00
args = sscanf ( buf , " %i %i " , & mvm - > dbgfs_prph_reg_addr , & value ) ;
/* if we only want to set the reg address - nothing more to do */
if ( args = = 1 )
goto out ;
/* otherwise, make sure we have both address and value */
if ( args ! = 2 )
return - EINVAL ;
2014-07-01 18:38:38 +03:00
ret = iwl_mvm_ref_sync ( mvm , IWL_MVM_REF_PRPH_WRITE ) ;
if ( ret )
return ret ;
2014-01-09 13:12:54 +02:00
iwl_write_prph ( mvm - > trans , mvm - > dbgfs_prph_reg_addr , value ) ;
2014-07-01 18:38:38 +03:00
iwl_mvm_unref ( mvm , IWL_MVM_REF_PRPH_WRITE ) ;
2014-01-09 13:12:54 +02:00
out :
return count ;
}
MVM_DEBUGFS_READ_WRITE_FILE_OPS ( prph_reg , 64 ) ;
2013-01-24 14:25:36 +01:00
/* Device wide debugfs entries */
2013-11-13 09:10:21 +01:00
MVM_DEBUGFS_WRITE_FILE_OPS ( tx_flush , 16 ) ;
MVM_DEBUGFS_WRITE_FILE_OPS ( sta_drain , 8 ) ;
MVM_DEBUGFS_READ_WRITE_FILE_OPS ( sram , 64 ) ;
2014-07-17 16:41:14 +03:00
MVM_DEBUGFS_READ_WRITE_FILE_OPS ( set_nic_temperature , 64 ) ;
2013-01-24 14:25:36 +01:00
MVM_DEBUGFS_READ_FILE_OPS ( stations ) ;
2013-02-19 11:02:36 +02:00
MVM_DEBUGFS_READ_FILE_OPS ( bt_notif ) ;
2013-06-30 07:43:28 +03:00
MVM_DEBUGFS_READ_FILE_OPS ( bt_cmd ) ;
2013-11-13 09:10:21 +01:00
MVM_DEBUGFS_READ_WRITE_FILE_OPS ( disable_power_off , 64 ) ;
2013-07-30 15:29:37 +03:00
MVM_DEBUGFS_READ_FILE_OPS ( fw_rx_stats ) ;
2014-01-28 01:35:32 +02:00
MVM_DEBUGFS_READ_FILE_OPS ( drv_rx_stats ) ;
2013-11-13 09:10:21 +01:00
MVM_DEBUGFS_WRITE_FILE_OPS ( fw_restart , 10 ) ;
MVM_DEBUGFS_WRITE_FILE_OPS ( fw_nmi , 10 ) ;
2014-03-16 21:55:43 +02:00
MVM_DEBUGFS_WRITE_FILE_OPS ( bt_tx_prio , 10 ) ;
2014-05-28 12:06:41 +03:00
MVM_DEBUGFS_WRITE_FILE_OPS ( bt_force_ant , 10 ) ;
2013-11-13 09:10:21 +01:00
MVM_DEBUGFS_READ_WRITE_FILE_OPS ( scan_ant_rxchain , 8 ) ;
2013-11-11 18:56:35 +02:00
MVM_DEBUGFS_READ_WRITE_FILE_OPS ( d0i3_refs , 8 ) ;
2013-08-19 08:36:48 +03:00
2014-03-18 21:15:06 +02:00
static const struct file_operations iwl_dbgfs_fw_error_dump_ops = {
2014-04-13 09:38:48 +03:00
. open = iwl_dbgfs_fw_error_dump_open ,
. read = iwl_dbgfs_fw_error_dump_read ,
. release = iwl_dbgfs_fw_error_dump_release ,
2014-03-18 21:15:06 +02:00
} ;
2014-01-08 10:11:12 +02:00
# ifdef CONFIG_IWLWIFI_BCAST_FILTERING
MVM_DEBUGFS_READ_WRITE_FILE_OPS ( bcast_filters , 256 ) ;
MVM_DEBUGFS_READ_WRITE_FILE_OPS ( bcast_filters_macs , 256 ) ;
# endif
2013-05-03 11:44:16 +02:00
# ifdef CONFIG_PM_SLEEP
2013-11-13 09:10:21 +01:00
MVM_DEBUGFS_READ_WRITE_FILE_OPS ( d3_sram , 8 ) ;
2013-05-03 11:44:16 +02:00
# endif
2013-01-24 14:25:36 +01:00
int iwl_mvm_dbgfs_register ( struct iwl_mvm * mvm , struct dentry * dbgfs_dir )
{
2014-01-08 10:11:12 +02:00
struct dentry * bcast_dir __maybe_unused ;
2013-01-24 14:25:36 +01:00
char buf [ 100 ] ;
2014-02-26 11:25:58 +01:00
spin_lock_init ( & mvm - > drv_stats_lock ) ;
2013-01-24 14:25:36 +01:00
mvm - > debugfs_dir = dbgfs_dir ;
MVM_DEBUGFS_ADD_FILE ( tx_flush , mvm - > debugfs_dir , S_IWUSR ) ;
MVM_DEBUGFS_ADD_FILE ( sta_drain , mvm - > debugfs_dir , S_IWUSR ) ;
MVM_DEBUGFS_ADD_FILE ( sram , mvm - > debugfs_dir , S_IWUSR | S_IRUSR ) ;
2014-07-17 16:41:14 +03:00
MVM_DEBUGFS_ADD_FILE ( set_nic_temperature , mvm - > debugfs_dir ,
S_IWUSR | S_IRUSR ) ;
2013-01-24 14:25:36 +01:00
MVM_DEBUGFS_ADD_FILE ( stations , dbgfs_dir , S_IRUSR ) ;
2014-03-18 21:15:06 +02:00
MVM_DEBUGFS_ADD_FILE ( fw_error_dump , dbgfs_dir , S_IRUSR ) ;
2013-02-19 11:02:36 +02:00
MVM_DEBUGFS_ADD_FILE ( bt_notif , dbgfs_dir , S_IRUSR ) ;
2013-06-30 07:43:28 +03:00
MVM_DEBUGFS_ADD_FILE ( bt_cmd , dbgfs_dir , S_IRUSR ) ;
2014-03-30 10:11:13 +03:00
MVM_DEBUGFS_ADD_FILE ( disable_power_off , mvm - > debugfs_dir ,
S_IRUSR | S_IWUSR ) ;
2013-07-30 15:29:37 +03:00
MVM_DEBUGFS_ADD_FILE ( fw_rx_stats , mvm - > debugfs_dir , S_IRUSR ) ;
2014-01-28 01:35:32 +02:00
MVM_DEBUGFS_ADD_FILE ( drv_rx_stats , mvm - > debugfs_dir , S_IRUSR ) ;
2013-03-04 08:53:07 +02:00
MVM_DEBUGFS_ADD_FILE ( fw_restart , mvm - > debugfs_dir , S_IWUSR ) ;
2013-10-17 14:26:50 +02:00
MVM_DEBUGFS_ADD_FILE ( fw_nmi , mvm - > debugfs_dir , S_IWUSR ) ;
2014-03-16 21:55:43 +02:00
MVM_DEBUGFS_ADD_FILE ( bt_tx_prio , mvm - > debugfs_dir , S_IWUSR ) ;
2014-05-28 12:06:41 +03:00
MVM_DEBUGFS_ADD_FILE ( bt_force_ant , mvm - > debugfs_dir , S_IWUSR ) ;
2013-08-19 08:36:48 +03:00
MVM_DEBUGFS_ADD_FILE ( scan_ant_rxchain , mvm - > debugfs_dir ,
S_IWUSR | S_IRUSR ) ;
2014-01-09 13:12:54 +02:00
MVM_DEBUGFS_ADD_FILE ( prph_reg , mvm - > debugfs_dir , S_IWUSR | S_IRUSR ) ;
2013-11-11 18:56:35 +02:00
MVM_DEBUGFS_ADD_FILE ( d0i3_refs , mvm - > debugfs_dir , S_IRUSR | S_IWUSR ) ;
2014-01-08 10:11:12 +02:00
# ifdef CONFIG_IWLWIFI_BCAST_FILTERING
if ( mvm - > fw - > ucode_capa . flags & IWL_UCODE_TLV_FLAGS_BCAST_FILTERING ) {
bcast_dir = debugfs_create_dir ( " bcast_filtering " ,
mvm - > debugfs_dir ) ;
if ( ! bcast_dir )
goto err ;
if ( ! debugfs_create_bool ( " override " , S_IRUSR | S_IWUSR ,
bcast_dir ,
& mvm - > dbgfs_bcast_filtering . override ) )
goto err ;
MVM_DEBUGFS_ADD_FILE_ALIAS ( " filters " , bcast_filters ,
bcast_dir , S_IWUSR | S_IRUSR ) ;
MVM_DEBUGFS_ADD_FILE_ALIAS ( " macs " , bcast_filters_macs ,
bcast_dir , S_IWUSR | S_IRUSR ) ;
}
# endif
2013-05-03 11:44:16 +02:00
# ifdef CONFIG_PM_SLEEP
MVM_DEBUGFS_ADD_FILE ( d3_sram , mvm - > debugfs_dir , S_IRUSR | S_IWUSR ) ;
2013-05-14 13:53:45 +02:00
MVM_DEBUGFS_ADD_FILE ( d3_test , mvm - > debugfs_dir , S_IRUSR ) ;
2013-06-12 14:55:40 +02:00
if ( ! debugfs_create_bool ( " d3_wake_sysassert " , S_IRUSR | S_IWUSR ,
mvm - > debugfs_dir , & mvm - > d3_wake_sysassert ) )
goto err ;
2013-05-03 11:44:16 +02:00
# endif
2013-01-24 14:25:36 +01:00
2014-08-28 02:21:05 +03:00
if ( ! debugfs_create_u8 ( " low_latency_agg_frame_limit " , S_IRUSR | S_IWUSR ,
mvm - > debugfs_dir ,
& mvm - > low_latency_agg_frame_limit ) )
goto err ;
2014-08-07 18:08:56 +03:00
if ( ! debugfs_create_u8 ( " ps_disabled " , S_IRUSR ,
mvm - > debugfs_dir , & mvm - > ps_disabled ) )
goto err ;
2013-11-18 17:00:03 +02:00
if ( ! debugfs_create_blob ( " nvm_hw " , S_IRUSR ,
mvm - > debugfs_dir , & mvm - > nvm_hw_blob ) )
goto err ;
if ( ! debugfs_create_blob ( " nvm_sw " , S_IRUSR ,
mvm - > debugfs_dir , & mvm - > nvm_sw_blob ) )
goto err ;
if ( ! debugfs_create_blob ( " nvm_calib " , S_IRUSR ,
mvm - > debugfs_dir , & mvm - > nvm_calib_blob ) )
goto err ;
if ( ! debugfs_create_blob ( " nvm_prod " , S_IRUSR ,
mvm - > debugfs_dir , & mvm - > nvm_prod_blob ) )
goto err ;
2013-01-24 14:25:36 +01:00
/*
* Create a symlink with mac80211 . It will be removed when mac80211
* exists ( before the opmode exists which removes the target . )
*/
snprintf ( buf , 100 , " ../../%s/%s " ,
dbgfs_dir - > d_parent - > d_parent - > d_name . name ,
dbgfs_dir - > d_parent - > d_name . name ) ;
if ( ! debugfs_create_symlink ( " iwlwifi " , mvm - > hw - > wiphy - > debugfsdir , buf ) )
goto err ;
return 0 ;
err :
IWL_ERR ( mvm , " Can't create the mvm debugfs directory \n " ) ;
return - ENOMEM ;
}