Skip to content

Commit

Permalink
iwlagn: clean up & autodetect statistics
Browse files Browse the repository at this point in the history
There's no need to keep both normal and BT statistics
versions around all the time in memory when we only
use a subset of both. So keep only the subsets that
we need in memory, depending on the debug config).

Also, in doing so, we can remove all the calls to
iwl_bt_statistics() in the driver as we'll just
access the copied statistics now.

Finally, also remove this call from the one place
where it might still be needed and automatically
detect what kind of statistics the device is sending
based on their size. This way, we don't need to keep
track of which devices do what any more, which is
good since this is subject to change based on the
ucode version (as some ucode even for non-BT devices
will in fact use BT statistics).

Warn upon encountering a statistics command from the
ucode that isn't known, so we will find such issues
earlier in the future.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Tested-by: Don Fry <donald.h.fry@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
  • Loading branch information
Johannes Berg authored and Wey-Yi Guy committed Apr 8, 2011
1 parent 703bc58 commit 0da0e5b
Show file tree
Hide file tree
Showing 13 changed files with 243 additions and 376 deletions.
1 change: 0 additions & 1 deletion drivers/net/wireless/iwlwifi/iwl-2000.c
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,6 @@ static struct iwl_ht_params iwl2000_ht_params = {
};

static struct iwl_bt_params iwl2030_bt_params = {
.bt_statistics = true,
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
.advanced_bt_coexist = true,
.agg_time_limit = BT_AGG_THRESHOLD_DEF,
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/iwlwifi/iwl-5000.c
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ static void iwl5150_temperature(struct iwl_priv *priv)
u32 vt = 0;
s32 offset = iwl_temp_calib_to_offset(priv);

vt = le32_to_cpu(priv->_agn.statistics.general.common.temperature);
vt = le32_to_cpu(priv->statistics.common.temperature);
vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset;
/* now vt hold the temperature in Kelvin */
priv->temperature = KELVIN_TO_CELSIUS(vt);
Expand Down
1 change: 0 additions & 1 deletion drivers/net/wireless/iwlwifi/iwl-6000.c
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,6 @@ static struct iwl_ht_params iwl6000_ht_params = {
};

static struct iwl_bt_params iwl6000_bt_params = {
.bt_statistics = true,
/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
.advanced_bt_coexist = true,
.agg_time_limit = BT_AGG_THRESHOLD_DEF,
Expand Down
43 changes: 11 additions & 32 deletions drivers/net/wireless/iwlwifi/iwl-agn-calib.c
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ void iwl_init_sensitivity(struct iwl_priv *priv)
IWL_DEBUG_CALIB(priv, "<<return 0x%X\n", ret);
}

void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp)
void iwl_sensitivity_calibration(struct iwl_priv *priv)
{
u32 rx_enable_time;
u32 fa_cck;
Expand All @@ -631,16 +631,9 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp)
}

spin_lock_irqsave(&priv->lock, flags);
if (iwl_bt_statistics(priv)) {
rx_info = &(((struct iwl_bt_notif_statistics *)resp)->
rx.general.common);
ofdm = &(((struct iwl_bt_notif_statistics *)resp)->rx.ofdm);
cck = &(((struct iwl_bt_notif_statistics *)resp)->rx.cck);
} else {
rx_info = &(((struct iwl_notif_statistics *)resp)->rx.general);
ofdm = &(((struct iwl_notif_statistics *)resp)->rx.ofdm);
cck = &(((struct iwl_notif_statistics *)resp)->rx.cck);
}
rx_info = &priv->statistics.rx_non_phy;
ofdm = &priv->statistics.rx_ofdm;
cck = &priv->statistics.rx_cck;
if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
IWL_DEBUG_CALIB(priv, "<< invalid data.\n");
spin_unlock_irqrestore(&priv->lock, flags);
Expand Down Expand Up @@ -851,7 +844,7 @@ static void iwl_find_disconn_antenna(struct iwl_priv *priv, u32* average_sig,
* 1) Which antennas are connected.
* 2) Differential rx gain settings to balance the 3 receivers.
*/
void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
void iwl_chain_noise_calibration(struct iwl_priv *priv)
{
struct iwl_chain_noise_data *data = NULL;

Expand Down Expand Up @@ -896,13 +889,9 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
}

spin_lock_irqsave(&priv->lock, flags);
if (iwl_bt_statistics(priv)) {
rx_info = &(((struct iwl_bt_notif_statistics *)stat_resp)->
rx.general.common);
} else {
rx_info = &(((struct iwl_notif_statistics *)stat_resp)->
rx.general);
}

rx_info = &priv->statistics.rx_non_phy;

if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
IWL_DEBUG_CALIB(priv, " << Interference data unavailable\n");
spin_unlock_irqrestore(&priv->lock, flags);
Expand All @@ -911,19 +900,9 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)

rxon_band24 = !!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK);
rxon_chnum = le16_to_cpu(ctx->staging.channel);
if (iwl_bt_statistics(priv)) {
stat_band24 = !!(((struct iwl_bt_notif_statistics *)
stat_resp)->flag &
STATISTICS_REPLY_FLG_BAND_24G_MSK);
stat_chnum = le32_to_cpu(((struct iwl_bt_notif_statistics *)
stat_resp)->flag) >> 16;
} else {
stat_band24 = !!(((struct iwl_notif_statistics *)
stat_resp)->flag &
STATISTICS_REPLY_FLG_BAND_24G_MSK);
stat_chnum = le32_to_cpu(((struct iwl_notif_statistics *)
stat_resp)->flag) >> 16;
}
stat_band24 =
!!(priv->statistics.flag & STATISTICS_REPLY_FLG_BAND_24G_MSK);
stat_chnum = le32_to_cpu(priv->statistics.flag) >> 16;

/* Make sure we accumulate data for just the associated channel
* (even if scanning). */
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/wireless/iwlwifi/iwl-agn-calib.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@
#include "iwl-core.h"
#include "iwl-commands.h"

void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp);
void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp);
void iwl_chain_noise_calibration(struct iwl_priv *priv);
void iwl_sensitivity_calibration(struct iwl_priv *priv);

void iwl_init_sensitivity(struct iwl_priv *priv);
void iwl_reset_run_time_calib(struct iwl_priv *priv);
Expand Down
134 changes: 43 additions & 91 deletions drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,7 @@ static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
int p = 0;
u32 flag;

if (iwl_bt_statistics(priv))
flag = le32_to_cpu(priv->_agn.statistics_bt.flag);
else
flag = le32_to_cpu(priv->_agn.statistics.flag);
flag = le32_to_cpu(priv->statistics.flag);

p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag);
if (flag & UCODE_STATISTICS_CLEAR_MSK)
Expand Down Expand Up @@ -88,43 +85,22 @@ ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
* the last statistics notification from uCode
* might not reflect the current uCode activity
*/
if (iwl_bt_statistics(priv)) {
ofdm = &priv->_agn.statistics_bt.rx.ofdm;
cck = &priv->_agn.statistics_bt.rx.cck;
general = &priv->_agn.statistics_bt.rx.general.common;
ht = &priv->_agn.statistics_bt.rx.ofdm_ht;
accum_ofdm = &priv->_agn.accum_statistics_bt.rx.ofdm;
accum_cck = &priv->_agn.accum_statistics_bt.rx.cck;
accum_general =
&priv->_agn.accum_statistics_bt.rx.general.common;
accum_ht = &priv->_agn.accum_statistics_bt.rx.ofdm_ht;
delta_ofdm = &priv->_agn.delta_statistics_bt.rx.ofdm;
delta_cck = &priv->_agn.delta_statistics_bt.rx.cck;
delta_general =
&priv->_agn.delta_statistics_bt.rx.general.common;
delta_ht = &priv->_agn.delta_statistics_bt.rx.ofdm_ht;
max_ofdm = &priv->_agn.max_delta_bt.rx.ofdm;
max_cck = &priv->_agn.max_delta_bt.rx.cck;
max_general = &priv->_agn.max_delta_bt.rx.general.common;
max_ht = &priv->_agn.max_delta_bt.rx.ofdm_ht;
} else {
ofdm = &priv->_agn.statistics.rx.ofdm;
cck = &priv->_agn.statistics.rx.cck;
general = &priv->_agn.statistics.rx.general;
ht = &priv->_agn.statistics.rx.ofdm_ht;
accum_ofdm = &priv->_agn.accum_statistics.rx.ofdm;
accum_cck = &priv->_agn.accum_statistics.rx.cck;
accum_general = &priv->_agn.accum_statistics.rx.general;
accum_ht = &priv->_agn.accum_statistics.rx.ofdm_ht;
delta_ofdm = &priv->_agn.delta_statistics.rx.ofdm;
delta_cck = &priv->_agn.delta_statistics.rx.cck;
delta_general = &priv->_agn.delta_statistics.rx.general;
delta_ht = &priv->_agn.delta_statistics.rx.ofdm_ht;
max_ofdm = &priv->_agn.max_delta.rx.ofdm;
max_cck = &priv->_agn.max_delta.rx.cck;
max_general = &priv->_agn.max_delta.rx.general;
max_ht = &priv->_agn.max_delta.rx.ofdm_ht;
}
ofdm = &priv->statistics.rx_ofdm;
cck = &priv->statistics.rx_cck;
general = &priv->statistics.rx_non_phy;
ht = &priv->statistics.rx_ofdm_ht;
accum_ofdm = &priv->accum_stats.rx_ofdm;
accum_cck = &priv->accum_stats.rx_cck;
accum_general = &priv->accum_stats.rx_non_phy;
accum_ht = &priv->accum_stats.rx_ofdm_ht;
delta_ofdm = &priv->delta_stats.rx_ofdm;
delta_cck = &priv->delta_stats.rx_cck;
delta_general = &priv->delta_stats.rx_non_phy;
delta_ht = &priv->delta_stats.rx_ofdm_ht;
max_ofdm = &priv->max_delta_stats.rx_ofdm;
max_cck = &priv->max_delta_stats.rx_cck;
max_general = &priv->max_delta_stats.rx_non_phy;
max_ht = &priv->max_delta_stats.rx_ofdm_ht;

pos += iwl_statistics_flag(priv, buf, bufsz);
pos += scnprintf(buf + pos, bufsz - pos,
Expand Down Expand Up @@ -531,20 +507,13 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file,
}

/* the statistic information display here is based on
* the last statistics notification from uCode
* might not reflect the current uCode activity
*/
if (iwl_bt_statistics(priv)) {
tx = &priv->_agn.statistics_bt.tx;
accum_tx = &priv->_agn.accum_statistics_bt.tx;
delta_tx = &priv->_agn.delta_statistics_bt.tx;
max_tx = &priv->_agn.max_delta_bt.tx;
} else {
tx = &priv->_agn.statistics.tx;
accum_tx = &priv->_agn.accum_statistics.tx;
delta_tx = &priv->_agn.delta_statistics.tx;
max_tx = &priv->_agn.max_delta.tx;
}
* the last statistics notification from uCode
* might not reflect the current uCode activity
*/
tx = &priv->statistics.tx;
accum_tx = &priv->accum_stats.tx;
delta_tx = &priv->delta_stats.tx;
max_tx = &priv->max_delta_stats.tx;

pos += iwl_statistics_flag(priv, buf, bufsz);
pos += scnprintf(buf + pos, bufsz - pos,
Expand Down Expand Up @@ -731,36 +700,21 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
}

/* the statistic information display here is based on
* the last statistics notification from uCode
* might not reflect the current uCode activity
*/
if (iwl_bt_statistics(priv)) {
general = &priv->_agn.statistics_bt.general.common;
dbg = &priv->_agn.statistics_bt.general.common.dbg;
div = &priv->_agn.statistics_bt.general.common.div;
accum_general = &priv->_agn.accum_statistics_bt.general.common;
accum_dbg = &priv->_agn.accum_statistics_bt.general.common.dbg;
accum_div = &priv->_agn.accum_statistics_bt.general.common.div;
delta_general = &priv->_agn.delta_statistics_bt.general.common;
max_general = &priv->_agn.max_delta_bt.general.common;
delta_dbg = &priv->_agn.delta_statistics_bt.general.common.dbg;
max_dbg = &priv->_agn.max_delta_bt.general.common.dbg;
delta_div = &priv->_agn.delta_statistics_bt.general.common.div;
max_div = &priv->_agn.max_delta_bt.general.common.div;
} else {
general = &priv->_agn.statistics.general.common;
dbg = &priv->_agn.statistics.general.common.dbg;
div = &priv->_agn.statistics.general.common.div;
accum_general = &priv->_agn.accum_statistics.general.common;
accum_dbg = &priv->_agn.accum_statistics.general.common.dbg;
accum_div = &priv->_agn.accum_statistics.general.common.div;
delta_general = &priv->_agn.delta_statistics.general.common;
max_general = &priv->_agn.max_delta.general.common;
delta_dbg = &priv->_agn.delta_statistics.general.common.dbg;
max_dbg = &priv->_agn.max_delta.general.common.dbg;
delta_div = &priv->_agn.delta_statistics.general.common.div;
max_div = &priv->_agn.max_delta.general.common.div;
}
* the last statistics notification from uCode
* might not reflect the current uCode activity
*/
general = &priv->statistics.common;
dbg = &priv->statistics.common.dbg;
div = &priv->statistics.common.div;
accum_general = &priv->accum_stats.common;
accum_dbg = &priv->accum_stats.common.dbg;
accum_div = &priv->accum_stats.common.div;
delta_general = &priv->delta_stats.common;
max_general = &priv->max_delta_stats.common;
delta_dbg = &priv->delta_stats.common.dbg;
max_dbg = &priv->max_delta_stats.common.dbg;
delta_div = &priv->delta_stats.common.div;
max_div = &priv->max_delta_stats.common.div;

pos += iwl_statistics_flag(priv, buf, bufsz);
pos += scnprintf(buf + pos, bufsz - pos,
Expand Down Expand Up @@ -876,8 +830,8 @@ ssize_t iwl_ucode_bt_stats_read(struct file *file,
* 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;
bt = &priv->statistics.bt_activity;
accum_bt = &priv->accum_stats.bt_activity;

pos += iwl_statistics_flag(priv, buf, bufsz);
pos += scnprintf(buf + pos, bufsz - pos, "Statistics_BT:\n");
Expand Down Expand Up @@ -918,10 +872,8 @@ ssize_t iwl_ucode_bt_stats_read(struct file *file,

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);
le32_to_cpu(priv->statistics.num_bt_kills),
priv->statistics.accum_num_bt_kills);

ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
kfree(buf);
Expand Down
4 changes: 1 addition & 3 deletions drivers/net/wireless/iwlwifi/iwl-agn-lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -549,9 +549,7 @@ int iwlagn_send_tx_power(struct iwl_priv *priv)
void iwlagn_temperature(struct iwl_priv *priv)
{
/* store temperature from correct statistics (in Celsius) */
priv->temperature = le32_to_cpu((iwl_bt_statistics(priv)) ?
priv->_agn.statistics_bt.general.common.temperature :
priv->_agn.statistics.general.common.temperature);
priv->temperature = le32_to_cpu(priv->statistics.common.temperature);
iwl_tt_handler(priv);
}

Expand Down
17 changes: 2 additions & 15 deletions drivers/net/wireless/iwlwifi/iwl-agn.c
Original file line number Diff line number Diff line change
Expand Up @@ -1705,10 +1705,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
else
priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;

if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BTSTATS ||
(priv->cfg->bt_params && priv->cfg->bt_params->bt_statistics))
priv->bt_statistics = true;

/* Copy images into buffers for card's bus-master reads ... */

/* Runtime instructions (first block of data in file) */
Expand Down Expand Up @@ -2626,17 +2622,8 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work)
}

if (priv->start_calib) {
if (iwl_bt_statistics(priv)) {
iwl_chain_noise_calibration(priv,
(void *)&priv->_agn.statistics_bt);
iwl_sensitivity_calibration(priv,
(void *)&priv->_agn.statistics_bt);
} else {
iwl_chain_noise_calibration(priv,
(void *)&priv->_agn.statistics);
iwl_sensitivity_calibration(priv,
(void *)&priv->_agn.statistics);
}
iwl_chain_noise_calibration(priv);
iwl_sensitivity_calibration(priv);
}

mutex_unlock(&priv->mutex);
Expand Down
Loading

0 comments on commit 0da0e5b

Please sign in to comment.