iwlwifi: mvm: allow to force the Rx chains from debugfs
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Sun, 8 Feb 2015 08:56:43 +0000 (10:56 +0200)
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Mon, 2 Mar 2015 06:20:27 +0000 (08:20 +0200)
This is useful to debug weird antenna problems.

Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
drivers/net/wireless/iwlwifi/mvm/mvm.h
drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c

index 5fe14591e1c41f06d0f9c4893290165b3ea7674e..7faad90386b8718b870bcaa025c98fdfe32111ce 100644 (file)
@@ -545,6 +545,57 @@ static ssize_t iwl_dbgfs_uapsd_misbehaving_write(struct ieee80211_vif *vif,
        return ret ? count : -EINVAL;
 }
 
+static ssize_t iwl_dbgfs_rx_phyinfo_write(struct ieee80211_vif *vif, char *buf,
+                                         size_t count, loff_t *ppos)
+{
+       struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+       struct iwl_mvm *mvm = mvmvif->mvm;
+       struct ieee80211_chanctx_conf *chanctx_conf;
+       struct iwl_mvm_phy_ctxt *phy_ctxt;
+       u16 value;
+       int ret;
+
+       ret = kstrtou16(buf, 0, &value);
+       if (ret)
+               return ret;
+
+       mutex_lock(&mvm->mutex);
+       rcu_read_lock();
+
+       chanctx_conf = rcu_dereference(vif->chanctx_conf);
+       /* make sure the channel context is assigned */
+       if (!chanctx_conf) {
+               rcu_read_unlock();
+               mutex_unlock(&mvm->mutex);
+               return -EINVAL;
+       }
+
+       phy_ctxt = &mvm->phy_ctxts[*(u16 *)chanctx_conf->drv_priv];
+       rcu_read_unlock();
+
+       mvm->dbgfs_rx_phyinfo = value;
+
+       ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &chanctx_conf->min_def,
+                                      chanctx_conf->rx_chains_static,
+                                      chanctx_conf->rx_chains_dynamic);
+       mutex_unlock(&mvm->mutex);
+
+       return ret ?: count;
+}
+
+static ssize_t iwl_dbgfs_rx_phyinfo_read(struct file *file,
+                                        char __user *user_buf,
+                                        size_t count, loff_t *ppos)
+{
+       struct ieee80211_vif *vif = file->private_data;
+       struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+       char buf[8];
+
+       snprintf(buf, sizeof(buf), "0x%04x\n", mvmvif->mvm->dbgfs_rx_phyinfo);
+
+       return simple_read_from_buffer(user_buf, count, ppos, buf, sizeof(buf));
+}
+
 #define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
        _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct ieee80211_vif)
 #define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
@@ -560,6 +611,7 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(pm_params, 32);
 MVM_DEBUGFS_READ_WRITE_FILE_OPS(bf_params, 256);
 MVM_DEBUGFS_READ_WRITE_FILE_OPS(low_latency, 10);
 MVM_DEBUGFS_READ_WRITE_FILE_OPS(uapsd_misbehaving, 20);
+MVM_DEBUGFS_READ_WRITE_FILE_OPS(rx_phyinfo, 10);
 
 void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
 {
@@ -595,6 +647,8 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
                                 S_IRUSR | S_IWUSR);
        MVM_DEBUGFS_ADD_FILE_VIF(uapsd_misbehaving, mvmvif->dbgfs_dir,
                                 S_IRUSR | S_IWUSR);
+       MVM_DEBUGFS_ADD_FILE_VIF(rx_phyinfo, mvmvif->dbgfs_dir,
+                                S_IRUSR | S_IWUSR);
 
        if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p &&
            mvmvif == mvm->bf_allowed_vif)
index f78a006df0e91d7ae40eec281b36760aff3ab2b4..885d09692fb6bb0b8d48c57163ef2054a249888e 100644 (file)
@@ -681,6 +681,7 @@ struct iwl_mvm {
 
        struct iwl_mvm_frame_stats drv_rx_stats;
        spinlock_t drv_stats_lock;
+       u16 dbgfs_rx_phyinfo;
 #endif
 
        struct iwl_mvm_phy_ctxt phy_ctxts[NUM_PHY_CTX];
index 5b43616eeb06332dedd68299650583ec292b201f..1bd10eda01f9873e1d610756713a775e7653a72c 100644 (file)
@@ -175,6 +175,8 @@ static void iwl_mvm_phy_ctxt_cmd_data(struct iwl_mvm *mvm,
        cmd->rxchain_info |= cpu_to_le32(idle_cnt << PHY_RX_CHAIN_CNT_POS);
        cmd->rxchain_info |= cpu_to_le32(active_cnt <<
                                         PHY_RX_CHAIN_MIMO_CNT_POS);
+       if (unlikely(mvm->dbgfs_rx_phyinfo))
+               cmd->rxchain_info = cpu_to_le32(mvm->dbgfs_rx_phyinfo);
 
        cmd->txchain_info = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm));
 }