iwlagn: add bluetooth stats to debugfs
authorWey-Yi Guy <wey-yi.w.guy@intel.com>
Wed, 14 Jul 2010 15:09:55 +0000 (08:09 -0700)
committerWey-Yi Guy <wey-yi.w.guy@intel.com>
Fri, 23 Jul 2010 15:41:32 +0000 (08:41 -0700)
For WiFi/BT combo devices, add bluetooth statistics counter
read function to debugfs.

Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
drivers/net/wireless/iwlwifi/iwl-1000.c
drivers/net/wireless/iwlwifi/iwl-4965.c
drivers/net/wireless/iwlwifi/iwl-5000.c
drivers/net/wireless/iwlwifi/iwl-6000.c
drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-debugfs.c

index c281d07ec5e51fb32dba30dd1a104183ca2b6f67..8848333bc3a9545e8ed6a9dd3d8905bfeee6e33f 100644 (file)
@@ -222,6 +222,7 @@ static struct iwl_lib_ops iwl1000_lib = {
                .rx_stats_read = iwl_ucode_rx_stats_read,
                .tx_stats_read = iwl_ucode_tx_stats_read,
                .general_stats_read = iwl_ucode_general_stats_read,
+               .bt_stats_read = iwl_ucode_bt_stats_read,
        },
        .recover_from_tx_stall = iwl_bg_monitor_recover,
        .check_plcp_health = iwl_good_plcp_health,
index 27a776f2f8fa487022003074df1476a3c0214fc9..d6531ad3906a5d2a407ff2c5c106a6cf335ead10 100644 (file)
@@ -2285,6 +2285,7 @@ static struct iwl_lib_ops iwl4965_lib = {
                .rx_stats_read = iwl_ucode_rx_stats_read,
                .tx_stats_read = iwl_ucode_tx_stats_read,
                .general_stats_read = iwl_ucode_general_stats_read,
+               .bt_stats_read = iwl_ucode_bt_stats_read,
        },
        .recover_from_tx_stall = iwl_bg_monitor_recover,
        .check_plcp_health = iwl_good_plcp_health,
index a7077cd7afeeadbad6295012fded19ef4196445d..8093ce2804fb31d3fb5e00cbc7f49da19d9543b6 100644 (file)
@@ -398,6 +398,7 @@ static struct iwl_lib_ops iwl5000_lib = {
                .rx_stats_read = iwl_ucode_rx_stats_read,
                .tx_stats_read = iwl_ucode_tx_stats_read,
                .general_stats_read = iwl_ucode_general_stats_read,
+               .bt_stats_read = iwl_ucode_bt_stats_read,
        },
        .recover_from_tx_stall = iwl_bg_monitor_recover,
        .check_plcp_health = iwl_good_plcp_health,
index a4e58d85f8896da6b73cfad4c0515866926167ad..58270529a0e4efc4ea3198ce9aa27fc45d1c9707 100644 (file)
@@ -323,6 +323,7 @@ static struct iwl_lib_ops iwl6000_lib = {
                .rx_stats_read = iwl_ucode_rx_stats_read,
                .tx_stats_read = iwl_ucode_tx_stats_read,
                .general_stats_read = iwl_ucode_general_stats_read,
+               .bt_stats_read = iwl_ucode_bt_stats_read,
        },
        .recover_from_tx_stall = iwl_bg_monitor_recover,
        .check_plcp_health = iwl_good_plcp_health,
index 19d1e5e8626114c58b5ad7a56a9c8fc64e99aa98..f052c6d09b374da05ca891f0e0a6b2ed8f78671f 100644 (file)
@@ -924,3 +924,90 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
        kfree(buf);
        return ret;
 }
+
+ssize_t iwl_ucode_bt_stats_read(struct file *file,
+                               char __user *user_buf,
+                               size_t count, loff_t *ppos)
+{
+       struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+       int pos = 0;
+       char *buf;
+       int bufsz = (sizeof(struct statistics_bt_activity) * 24) + 200;
+       ssize_t ret;
+       struct statistics_bt_activity *bt, *accum_bt;
+
+       if (!iwl_is_alive(priv))
+               return -EAGAIN;
+
+       /* make request to uCode to retrieve statistics information */
+       mutex_lock(&priv->mutex);
+       ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
+       mutex_unlock(&priv->mutex);
+
+       if (ret) {
+               IWL_ERR(priv,
+                       "Error sending statistics request: %zd\n", ret);
+               return -EAGAIN;
+       }
+       buf = kzalloc(bufsz, GFP_KERNEL);
+       if (!buf) {
+               IWL_ERR(priv, "Can not allocate Buffer\n");
+               return -ENOMEM;
+       }
+
+       /*
+        * the statistic information display here is based on
+        * the last statistics notification from uCode
+        * might not reflect the current uCode activity
+        */
+       bt = &priv->_agn.statistics_bt.general.activity;
+       accum_bt = &priv->_agn.accum_statistics_bt.general.activity;
+
+       pos += iwl_statistics_flag(priv, buf, bufsz);
+       pos += scnprintf(buf + pos, bufsz - pos, "Statistics_BT:\n");
+       pos += scnprintf(buf + pos, bufsz - pos,
+                       "\t\t\tcurrent\t\t\taccumulative\n");
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "hi_priority_tx_req_cnt:\t\t%u\t\t\t%u\n",
+                        le32_to_cpu(bt->hi_priority_tx_req_cnt),
+                        accum_bt->hi_priority_tx_req_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "hi_priority_tx_denied_cnt:\t%u\t\t\t%u\n",
+                        le32_to_cpu(bt->hi_priority_tx_denied_cnt),
+                        accum_bt->hi_priority_tx_denied_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "lo_priority_tx_req_cnt:\t\t%u\t\t\t%u\n",
+                        le32_to_cpu(bt->lo_priority_tx_req_cnt),
+                        accum_bt->lo_priority_tx_req_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "lo_priority_rx_denied_cnt:\t%u\t\t\t%u\n",
+                        le32_to_cpu(bt->lo_priority_tx_denied_cnt),
+                        accum_bt->lo_priority_tx_denied_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "hi_priority_rx_req_cnt:\t\t%u\t\t\t%u\n",
+                        le32_to_cpu(bt->hi_priority_rx_req_cnt),
+                        accum_bt->hi_priority_rx_req_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "hi_priority_rx_denied_cnt:\t%u\t\t\t%u\n",
+                        le32_to_cpu(bt->hi_priority_rx_denied_cnt),
+                        accum_bt->hi_priority_rx_denied_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "lo_priority_rx_req_cnt:\t\t%u\t\t\t%u\n",
+                        le32_to_cpu(bt->lo_priority_rx_req_cnt),
+                        accum_bt->lo_priority_rx_req_cnt);
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "lo_priority_rx_denied_cnt:\t%u\t\t\t%u\n",
+                        le32_to_cpu(bt->lo_priority_rx_denied_cnt),
+                        accum_bt->lo_priority_rx_denied_cnt);
+
+       pos += scnprintf(buf + pos, bufsz - pos,
+                        "(rx)num_bt_kills:\t\t%u\t\t\t%u\n",
+                        le32_to_cpu(priv->_agn.statistics_bt.rx.
+                               general.num_bt_kills),
+                        priv->_agn.accum_statistics_bt.rx.
+                               general.num_bt_kills);
+
+       ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+       kfree(buf);
+       return ret;
+}
index 59b1f25f0d85bd9944bfae9a3f47d6c46005a92b..bbdce5913ac77a51d52fb02cbef8a587287b6b8e 100644 (file)
@@ -37,6 +37,8 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file, char __user *user_buf,
                                size_t count, loff_t *ppos);
 ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
                                     size_t count, loff_t *ppos);
+ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf,
+                               size_t count, loff_t *ppos);
 #else
 static ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
                                       size_t count, loff_t *ppos)
@@ -53,4 +55,9 @@ static ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user
 {
        return 0;
 }
+static ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf,
+                                      size_t count, loff_t *ppos)
+{
+       return 0;
+}
 #endif
index 2954a52a5e83640806cd3688075ddca1e2ee1511..b60cf45378904cbe37ce7006d21059f6357b6e60 100644 (file)
@@ -125,6 +125,8 @@ struct iwl_debugfs_ops {
                                 size_t count, loff_t *ppos);
        ssize_t (*general_stats_read)(struct file *file, char __user *user_buf,
                                      size_t count, loff_t *ppos);
+       ssize_t (*bt_stats_read)(struct file *file, char __user *user_buf,
+                                size_t count, loff_t *ppos);
 };
 
 struct iwl_temp_ops {
index 7b25d14683585f773e69f11657302f0715003c2a..e96a1bb12783db78efc0d07a2794599525f9f830 100644 (file)
@@ -1519,6 +1519,16 @@ static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file,
        return count;
 }
 
+static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file,
+                                       char __user *user_buf,
+                                       size_t count, loff_t *ppos)
+{
+       struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+
+       return priv->cfg->ops->lib->debugfs_ops.bt_stats_read(file,
+                       user_buf, count, ppos);
+}
+
 DEBUGFS_READ_FILE_OPS(rx_statistics);
 DEBUGFS_READ_FILE_OPS(tx_statistics);
 DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
@@ -1541,6 +1551,7 @@ DEBUGFS_READ_WRITE_FILE_OPS(force_reset);
 DEBUGFS_READ_FILE_OPS(rxon_flags);
 DEBUGFS_READ_FILE_OPS(rxon_filter_flags);
 DEBUGFS_WRITE_FILE_OPS(txfifo_flush);
+DEBUGFS_READ_FILE_OPS(ucode_bt_stats);
 
 /*
  * Create the debugfs files and directories
@@ -1608,6 +1619,8 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
                DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
        if (priv->cfg->ucode_tracing)
                DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
+       if (priv->cfg->bt_statistics)
+               DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR);
        DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
        DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
        if (priv->cfg->sensitivity_calib_by_driver)