Commit 17f36fc6 authored by Abhijeet Kolekar's avatar Abhijeet Kolekar Committed by Reinette Chatre

iwl3945: add ucode statistics

Add general, rx and tx uCode statistics to 3945. This will help
in debugging
Signed-off-by: default avatarAbhijeet Kolekar <abhijeet.kolekar@intel.com>
Signed-off-by: default avatarReinette Chatre <reinette.chatre@intel.com>
parent c2845d01
......@@ -22,5 +22,6 @@ iwlagn-$(CONFIG_IWL5000) += iwl-1000.o
# 3945
obj-$(CONFIG_IWL3945) += iwl3945.o
iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o iwl-3945-led.o
iwl3945-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-3945-debugfs.o
ccflags-y += -D__CHECK_ENDIAN__
This diff is collapsed.
/******************************************************************************
*
* GPL LICENSE SUMMARY
*
* Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
*
* 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
* in the file called LICENSE.GPL.
*
* Contact Information:
* Intel Linux Wireless <ilw@linux.intel.com>
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
*****************************************************************************/
#include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-debug.h"
#ifdef CONFIG_IWLWIFI_DEBUGFS
ssize_t iwl3945_ucode_rx_stats_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos);
ssize_t iwl3945_ucode_tx_stats_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos);
ssize_t iwl3945_ucode_general_stats_read(struct file *file,
char __user *user_buf, size_t count,
loff_t *ppos);
#else
static ssize_t iwl3945_ucode_rx_stats_read(struct file *file,
char __user *user_buf, size_t count,
loff_t *ppos)
{
return 0;
}
static ssize_t iwl3945_ucode_tx_stats_read(struct file *file,
char __user *user_buf, size_t count,
loff_t *ppos)
{
return 0;
}
static ssize_t iwl3945_ucode_general_stats_read(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
{
return 0;
}
#endif
......@@ -49,6 +49,7 @@
#include "iwl-helpers.h"
#include "iwl-led.h"
#include "iwl-3945-led.h"
#include "iwl-3945-debugfs.h"
#define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np) \
[IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \
......@@ -292,7 +293,7 @@ static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv,
* iwl3945_rx_reply_tx - Handle Tx response
*/
static void iwl3945_rx_reply_tx(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
struct iwl_rx_mem_buffer *rxb)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
u16 sequence = le16_to_cpu(pkt->hdr.sequence);
......@@ -350,18 +351,81 @@ static void iwl3945_rx_reply_tx(struct iwl_priv *priv,
* RX handler implementations
*
*****************************************************************************/
#ifdef CONFIG_IWLWIFI_DEBUG
/*
* based on the assumption of all statistics counter are in DWORD
* FIXME: This function is for debugging, do not deal with
* the case of counters roll-over.
*/
static void iwl3945_accumulative_statistics(struct iwl_priv *priv,
__le32 *stats)
{
int i;
__le32 *prev_stats;
u32 *accum_stats;
u32 *delta, *max_delta;
prev_stats = (__le32 *)&priv->_3945.statistics;
accum_stats = (u32 *)&priv->_3945.accum_statistics;
delta = (u32 *)&priv->_3945.delta_statistics;
max_delta = (u32 *)&priv->_3945.max_delta;
for (i = sizeof(__le32); i < sizeof(struct iwl3945_notif_statistics);
i += sizeof(__le32), stats++, prev_stats++, delta++,
max_delta++, accum_stats++) {
if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) {
*delta = (le32_to_cpu(*stats) -
le32_to_cpu(*prev_stats));
*accum_stats += *delta;
if (*delta > *max_delta)
*max_delta = *delta;
}
}
/* reset accumulative statistics for "no-counter" type statistics */
priv->_3945.accum_statistics.general.temperature =
priv->_3945.statistics.general.temperature;
priv->_3945.accum_statistics.general.ttl_timestamp =
priv->_3945.statistics.general.ttl_timestamp;
}
#endif
void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
(int)sizeof(struct iwl3945_notif_statistics),
le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
#ifdef CONFIG_IWLWIFI_DEBUG
iwl3945_accumulative_statistics(priv, (__le32 *)&pkt->u.raw);
#endif
memcpy(&priv->_3945.statistics, pkt->u.raw, sizeof(priv->_3945.statistics));
}
void iwl3945_reply_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
__le32 *flag = (__le32 *)&pkt->u.raw;
if (le32_to_cpu(*flag) & UCODE_STATISTICS_CLEAR_MSK) {
#ifdef CONFIG_IWLWIFI_DEBUG
memset(&priv->_3945.accum_statistics, 0,
sizeof(struct iwl3945_notif_statistics));
memset(&priv->_3945.delta_statistics, 0,
sizeof(struct iwl3945_notif_statistics));
memset(&priv->_3945.max_delta, 0,
sizeof(struct iwl3945_notif_statistics));
#endif
IWL_DEBUG_RX(priv, "Statistics have been cleared\n");
}
iwl3945_hw_rx_statistics(priv, rxb);
}
/******************************************************************************
*
* Misc. internal state and helper functions
......@@ -2735,6 +2799,12 @@ static struct iwl_lib_ops iwl3945_lib = {
.isr = iwl_isr_legacy,
.config_ap = iwl3945_config_ap,
.add_bcast_station = iwl3945_add_bcast_station,
.debugfs_ops = {
.rx_stats_read = iwl3945_ucode_rx_stats_read,
.tx_stats_read = iwl3945_ucode_tx_stats_read,
.general_stats_read = iwl3945_ucode_general_stats_read,
},
};
static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
......
......@@ -264,6 +264,8 @@ extern int iwl3945_hw_reg_send_txpower(struct iwl_priv *priv);
extern int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power);
extern void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
void iwl3945_reply_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
extern void iwl3945_disable_events(struct iwl_priv *priv);
extern int iwl4965_get_temperature(const struct iwl_priv *priv);
extern void iwl3945_post_associate(struct iwl_priv *priv);
......
......@@ -1053,10 +1053,8 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
size_t count, loff_t *ppos)
{
struct iwl_priv *priv = file->private_data;
if (priv->cfg->ops->lib->debugfs_ops.rx_stats_read)
return priv->cfg->ops->lib->debugfs_ops.rx_stats_read(file,
user_buf, count, ppos);
return 0;
return priv->cfg->ops->lib->debugfs_ops.rx_stats_read(file,
user_buf, count, ppos);
}
static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
......@@ -1064,10 +1062,8 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
size_t count, loff_t *ppos)
{
struct iwl_priv *priv = file->private_data;
if (priv->cfg->ops->lib->debugfs_ops.tx_stats_read)
return priv->cfg->ops->lib->debugfs_ops.tx_stats_read(file,
user_buf, count, ppos);
return 0;
return priv->cfg->ops->lib->debugfs_ops.tx_stats_read(file,
user_buf, count, ppos);
}
static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
......@@ -1075,10 +1071,8 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
size_t count, loff_t *ppos)
{
struct iwl_priv *priv = file->private_data;
if (priv->cfg->ops->lib->debugfs_ops.general_stats_read)
return priv->cfg->ops->lib->debugfs_ops.general_stats_read(file,
user_buf, count, ppos);
return 0;
return priv->cfg->ops->lib->debugfs_ops.general_stats_read(file,
user_buf, count, ppos);
}
static ssize_t iwl_dbgfs_sensitivity_read(struct file *file,
......
......@@ -1202,6 +1202,11 @@ struct iwl_priv {
struct delayed_work rfkill_poll;
struct iwl3945_notif_statistics statistics;
#ifdef CONFIG_IWLWIFI_DEBUG
struct iwl3945_notif_statistics accum_statistics;
struct iwl3945_notif_statistics delta_statistics;
struct iwl3945_notif_statistics max_delta;
#endif
u32 sta_supp_rates;
int last_rx_rssi; /* From Rx packet statistics */
......
......@@ -956,7 +956,7 @@ static void iwl3945_setup_rx_handlers(struct iwl_priv *priv)
* statistics request from the host as well as for the periodic
* statistics notifications (after received beacons) from the uCode.
*/
priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_hw_rx_statistics;
priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl3945_reply_statistics;
priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl3945_hw_rx_statistics;
iwl_setup_rx_scan_handlers(priv);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment