iwlwifi: mvm: add per-interface debugfs with mac_params file
authorJohannes Berg <johannes.berg@intel.com>
Tue, 26 Mar 2013 09:47:53 +0000 (10:47 +0100)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 3 Apr 2013 20:49:04 +0000 (22:49 +0200)
Use the per-interface debugfs infrastructure to create a
directory and symlink, and add a file containing debug
data related to each virtual interface.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/iwlwifi/mvm/debugfs.c
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/iwlwifi/mvm/mvm.h

index b080b4ba545806e3ddf4ebd980cc2975837c29ae..5cecb75241d1baddf6d3179bd89368947b316670 100644 (file)
@@ -300,6 +300,58 @@ static ssize_t iwl_dbgfs_power_down_d3_allow_write(struct file *file,
        return count;
 }
 
+static ssize_t iwl_dbgfs_mac_params_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);
+       struct iwl_mvm *mvm = mvmvif->dbgfs_data;
+       u8 ap_sta_id;
+       struct ieee80211_chanctx_conf *chanctx_conf;
+       char buf[512];
+       int bufsz = sizeof(buf);
+       int pos = 0;
+       int i;
+
+       mutex_lock(&mvm->mutex);
+
+       ap_sta_id = mvmvif->ap_sta_id;
+
+       pos += scnprintf(buf+pos, bufsz-pos, "mac id/color: %d / %d\n",
+                        mvmvif->id, mvmvif->color);
+       pos += scnprintf(buf+pos, bufsz-pos, "bssid: %pM\n",
+                        vif->bss_conf.bssid);
+       pos += scnprintf(buf+pos, bufsz-pos, "QoS:\n");
+       for (i = 0; i < ARRAY_SIZE(mvmvif->queue_params); i++) {
+               pos += scnprintf(buf+pos, bufsz-pos,
+                                "\t%d: txop:%d - cw_min:%d - cw_max = %d - aifs = %d upasd = %d\n",
+                                i, mvmvif->queue_params[i].txop,
+                                mvmvif->queue_params[i].cw_min,
+                                mvmvif->queue_params[i].cw_max,
+                                mvmvif->queue_params[i].aifs,
+                                mvmvif->queue_params[i].uapsd);
+       }
+
+       if (vif->type == NL80211_IFTYPE_STATION)
+               pos += scnprintf(buf+pos, bufsz-pos, "ap_sta_id %d\n",
+                                ap_sta_id);
+
+       rcu_read_lock();
+       chanctx_conf = rcu_dereference(vif->chanctx_conf);
+       if (chanctx_conf) {
+               pos += scnprintf(buf+pos, bufsz-pos,
+                                "idle rx chains %d, active rx chains: %d\n",
+                                chanctx_conf->rx_chains_static,
+                                chanctx_conf->rx_chains_dynamic);
+       }
+       rcu_read_unlock();
+
+       mutex_unlock(&mvm->mutex);
+
+       return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+}
+
 #define BT_MBOX_MSG(_notif, _num, _field)                                   \
        ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\
        >> BT_MBOX##_num##_##_field##_POS)
@@ -464,6 +516,9 @@ MVM_DEBUGFS_WRITE_FILE_OPS(power_down_allow);
 MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow);
 MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart);
 
+/* Interface specific debugfs entries */
+MVM_DEBUGFS_READ_FILE_OPS(mac_params);
+
 int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
 {
        char buf[100];
@@ -494,3 +549,58 @@ err:
        IWL_ERR(mvm, "Can't create the mvm debugfs directory\n");
        return -ENOMEM;
 }
+
+void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
+{
+       struct dentry *dbgfs_dir = vif->debugfs_dir;
+       struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+       char buf[100];
+
+       if (!dbgfs_dir)
+               return;
+
+       mvmvif->dbgfs_dir = debugfs_create_dir("iwlmvm", dbgfs_dir);
+       mvmvif->dbgfs_data = mvm;
+
+       if (!mvmvif->dbgfs_dir) {
+               IWL_ERR(mvm, "Failed to create debugfs directory under %s\n",
+                       dbgfs_dir->d_name.name);
+               return;
+       }
+
+       MVM_DEBUGFS_ADD_FILE_VIF(mac_params, mvmvif->dbgfs_dir,
+                                S_IRUSR);
+
+       /*
+        * Create symlink for convenience pointing to interface specific
+        * debugfs entries for the driver. For example, under
+        * /sys/kernel/debug/iwlwifi/0000\:02\:00.0/iwlmvm/
+        * find
+        * netdev:wlan0 -> ../../../ieee80211/phy0/netdev:wlan0/iwlmvm/
+        */
+       snprintf(buf, 100, "../../../%s/%s/%s/%s",
+                dbgfs_dir->d_parent->d_parent->d_name.name,
+                dbgfs_dir->d_parent->d_name.name,
+                dbgfs_dir->d_name.name,
+                mvmvif->dbgfs_dir->d_name.name);
+
+       mvmvif->dbgfs_slink = debugfs_create_symlink(dbgfs_dir->d_name.name,
+                                                    mvm->debugfs_dir, buf);
+       if (!mvmvif->dbgfs_slink)
+               IWL_ERR(mvm, "Can't create debugfs symbolic link under %s\n",
+                       dbgfs_dir->d_name.name);
+       return;
+err:
+       IWL_ERR(mvm, "Can't create debugfs entity\n");
+}
+
+void iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
+{
+       struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+
+       debugfs_remove(mvmvif->dbgfs_slink);
+       mvmvif->dbgfs_slink = NULL;
+
+       debugfs_remove_recursive(mvmvif->dbgfs_dir);
+       mvmvif->dbgfs_dir = NULL;
+}
index 3d193f8c33b618cadc50bad99626f973b275085a..e618830ce04d2807269557126a45792f377ea983 100644 (file)
@@ -562,6 +562,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
                mvm->p2p_device_vif = vif;
        }
 
+       iwl_mvm_vif_dbgfs_register(mvm, vif);
        goto out_unlock;
 
  out_unbind:
@@ -640,6 +641,8 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
 
        mutex_lock(&mvm->mutex);
 
+       iwl_mvm_vif_dbgfs_clean(mvm, vif);
+
        /*
         * For AP/GO interface, the tear down of the resources allocated to the
         * interface is be handled as part of the stop_ap flow.
index 53d58968e30ace324600e2eef6112973282058ec..d7ffa6f9506014cca6f10738f1cdecb90383bd0d 100644 (file)
@@ -212,6 +212,7 @@ struct iwl_mvm_vif {
 
 #ifdef CONFIG_IWLWIFI_DEBUGFS
        struct dentry *dbgfs_dir;
+       struct dentry *dbgfs_slink;
        void *dbgfs_data;
 #endif
 };
@@ -471,8 +472,8 @@ void iwl_mvm_cancel_scan(struct iwl_mvm *mvm);
 /* MVM debugfs */
 #ifdef CONFIG_IWLWIFI_DEBUGFS
 int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir);
-int iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
-                              struct dentry *dbgfs_dir);
+void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
+void iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
 void iwl_power_get_params(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
                          struct iwl_powertable_cmd *cmd);
 #else
@@ -481,6 +482,14 @@ static inline int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm,
 {
        return 0;
 }
+static inline void
+iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
+{
+}
+static inline void
+iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
+{
+}
 #endif /* CONFIG_IWLWIFI_DEBUGFS */
 
 /* rate scaling */