iwlwifi: pcie: add fake RF-kill to debugfs
In order to debug "hardware" RF-kill flows, add a low-level hook to allow changing the "hardware" RF-kill from debugfs. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
This commit is contained in:

committed by
Luca Coelho

parent
3a6e168baa
commit
fa4de7f7c3
@@ -404,6 +404,7 @@ struct iwl_trans_pcie {
|
|||||||
int ict_index;
|
int ict_index;
|
||||||
bool use_ict;
|
bool use_ict;
|
||||||
bool is_down;
|
bool is_down;
|
||||||
|
bool debug_rfkill;
|
||||||
struct isr_statistics isr_stats;
|
struct isr_statistics isr_stats;
|
||||||
|
|
||||||
spinlock_t irq_lock;
|
spinlock_t irq_lock;
|
||||||
@@ -675,6 +676,8 @@ static inline void iwl_enable_rfkill_int(struct iwl_trans *trans)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void iwl_pcie_handle_rfkill_irq(struct iwl_trans *trans);
|
||||||
|
|
||||||
static inline void iwl_wake_queue(struct iwl_trans *trans,
|
static inline void iwl_wake_queue(struct iwl_trans *trans,
|
||||||
struct iwl_txq *txq)
|
struct iwl_txq *txq)
|
||||||
{
|
{
|
||||||
@@ -713,7 +716,12 @@ static inline u8 get_cmd_index(struct iwl_txq *q, u32 index)
|
|||||||
|
|
||||||
static inline bool iwl_is_rfkill_set(struct iwl_trans *trans)
|
static inline bool iwl_is_rfkill_set(struct iwl_trans *trans)
|
||||||
{
|
{
|
||||||
lockdep_assert_held(&IWL_TRANS_GET_PCIE_TRANS(trans)->mutex);
|
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||||
|
|
||||||
|
lockdep_assert_held(&trans_pcie->mutex);
|
||||||
|
|
||||||
|
if (trans_pcie->debug_rfkill)
|
||||||
|
return true;
|
||||||
|
|
||||||
return !(iwl_read32(trans, CSR_GP_CNTRL) &
|
return !(iwl_read32(trans, CSR_GP_CNTRL) &
|
||||||
CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW);
|
CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW);
|
||||||
|
@@ -1509,7 +1509,7 @@ static u32 iwl_pcie_int_cause_ict(struct iwl_trans *trans)
|
|||||||
return inta;
|
return inta;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void iwl_pcie_handle_rfkill_irq(struct iwl_trans *trans)
|
void iwl_pcie_handle_rfkill_irq(struct iwl_trans *trans)
|
||||||
{
|
{
|
||||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||||
struct isr_statistics *isr_stats = &trans_pcie->isr_stats;
|
struct isr_statistics *isr_stats = &trans_pcie->isr_stats;
|
||||||
|
@@ -2461,11 +2461,50 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t iwl_dbgfs_rfkill_read(struct file *file,
|
||||||
|
char __user *user_buf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
struct iwl_trans *trans = file->private_data;
|
||||||
|
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||||
|
char buf[100];
|
||||||
|
int pos;
|
||||||
|
|
||||||
|
pos = scnprintf(buf, sizeof(buf), "debug: %d\nhw: %d\n",
|
||||||
|
trans_pcie->debug_rfkill,
|
||||||
|
!(iwl_read32(trans, CSR_GP_CNTRL) &
|
||||||
|
CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW));
|
||||||
|
|
||||||
|
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t iwl_dbgfs_rfkill_write(struct file *file,
|
||||||
|
const char __user *user_buf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
struct iwl_trans *trans = file->private_data;
|
||||||
|
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||||
|
bool old = trans_pcie->debug_rfkill;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = kstrtobool_from_user(user_buf, count, &trans_pcie->debug_rfkill);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
if (old == trans_pcie->debug_rfkill)
|
||||||
|
return count;
|
||||||
|
IWL_WARN(trans, "changing debug rfkill %d->%d\n",
|
||||||
|
old, trans_pcie->debug_rfkill);
|
||||||
|
iwl_pcie_handle_rfkill_irq(trans);
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
|
DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
|
||||||
DEBUGFS_READ_FILE_OPS(fh_reg);
|
DEBUGFS_READ_FILE_OPS(fh_reg);
|
||||||
DEBUGFS_READ_FILE_OPS(rx_queue);
|
DEBUGFS_READ_FILE_OPS(rx_queue);
|
||||||
DEBUGFS_READ_FILE_OPS(tx_queue);
|
DEBUGFS_READ_FILE_OPS(tx_queue);
|
||||||
DEBUGFS_WRITE_FILE_OPS(csr);
|
DEBUGFS_WRITE_FILE_OPS(csr);
|
||||||
|
DEBUGFS_READ_WRITE_FILE_OPS(rfkill);
|
||||||
|
|
||||||
/* Create the debugfs files and directories */
|
/* Create the debugfs files and directories */
|
||||||
int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans)
|
int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans)
|
||||||
@@ -2477,6 +2516,7 @@ int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans)
|
|||||||
DEBUGFS_ADD_FILE(interrupt, dir, S_IWUSR | S_IRUSR);
|
DEBUGFS_ADD_FILE(interrupt, dir, S_IWUSR | S_IRUSR);
|
||||||
DEBUGFS_ADD_FILE(csr, dir, S_IWUSR);
|
DEBUGFS_ADD_FILE(csr, dir, S_IWUSR);
|
||||||
DEBUGFS_ADD_FILE(fh_reg, dir, S_IRUSR);
|
DEBUGFS_ADD_FILE(fh_reg, dir, S_IRUSR);
|
||||||
|
DEBUGFS_ADD_FILE(rfkill, dir, S_IWUSR | S_IRUSR);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
Reference in New Issue
Block a user