From: Zhu Yi <yi.zhu@intel.com>
To: linville@tuxdriver.com
Cc: linux-wireless@vger.kernel.org, "Grumbach,
Emmanuel" <emmanuel.grumbach@intel.com>,
Tomas Winkler <tomas.winkler@intel.com>,
Zhu Yi <yi.zhu@intel.com>
Subject: [PATCH 33/39] iwlwifi: use the results from disconnected antenna algorithm
Date: Wed, 3 Sep 2008 11:26:53 +0800 [thread overview]
Message-ID: <1220412419-15404-34-git-send-email-yi.zhu@intel.com> (raw)
In-Reply-To: <1220412419-15404-33-git-send-email-yi.zhu@intel.com>
From: Grumbach, Emmanuel <emmanuel.grumbach@intel.com>
This patch makes usage of the results from disconnected antenna alg to
know how many antennas are connected.
It also synchronizes between the chain noise alg and the W/A that
disables power management during association. All the antennas must be
enables during the chain noise algorithm. Hence, power management is
restored only after the completion of the algorithm.
In the future, we will need to update the AP that we don't support MIMO
if there is only one antenna connected. We also need to update the rate
scaling algorithm.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Zhu Yi <yi.zhu@intel.com>
---
drivers/net/wireless/iwlwifi/iwl-agn.c | 6 ++++-
drivers/net/wireless/iwlwifi/iwl-calib.c | 15 +++++++++---
drivers/net/wireless/iwlwifi/iwl-core.c | 35 ++++++++++++++++++++++++------
drivers/net/wireless/iwlwifi/iwl-dev.h | 10 +++++---
drivers/net/wireless/iwlwifi/iwl-power.c | 26 +++++++++++-----------
drivers/net/wireless/iwlwifi/iwl-power.h | 2 +-
6 files changed, 64 insertions(+), 30 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 42cb3dd..45cdf31 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2558,7 +2558,11 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
iwl_activate_qos(priv, 0);
spin_unlock_irqrestore(&priv->lock, flags);
- iwl_power_enable_management(priv);
+ /* the chain noise calibration will enabled PM upon completion
+ * If chain noise has already been run, then we need to enable
+ * power management here */
+ if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE)
+ iwl_power_enable_management(priv);
/* Enable Rx differential gain and sensitivity calibrations */
iwl_chain_noise_reset(priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index 35fb4a4..72fbf47 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -808,13 +808,11 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
}
}
+ /* Save for use within RXON, TX, SCAN commands, etc. */
+ priv->chain_noise_data.active_chains = active_chains;
IWL_DEBUG_CALIB("active_chains (bitwise) = 0x%x\n",
active_chains);
- /* Save for use within RXON, TX, SCAN commands, etc. */
- /*priv->valid_antenna = active_chains;*/
- /*FIXME: should be reflected in RX chains in RXON */
-
/* Analyze noise for rx balance */
average_noise[0] = ((data->chain_noise_a)/CAL_NUM_OF_BEACONS);
average_noise[1] = ((data->chain_noise_b)/CAL_NUM_OF_BEACONS);
@@ -839,6 +837,15 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
priv->cfg->ops->utils->gain_computation(priv, average_noise,
min_average_noise_antenna_i, min_average_noise);
+
+ /* Some power changes may have been made during the calibration.
+ * Update and commit the RXON
+ */
+ if (priv->cfg->ops->lib->update_chain_flags)
+ priv->cfg->ops->lib->update_chain_flags(priv);
+
+ data->state = IWL_CHAIN_NOISE_DONE;
+ iwl_power_enable_management(priv);
}
EXPORT_SYMBOL(iwl_chain_noise_calibration);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index b29c84a..134f4ee 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -740,6 +740,17 @@ static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
return idle_cnt;
}
+/* up to 4 chains */
+static u8 iwl_count_chain_bitmap(u32 chain_bitmap)
+{
+ u8 res;
+ res = (chain_bitmap & BIT(0)) >> 0;
+ res += (chain_bitmap & BIT(1)) >> 1;
+ res += (chain_bitmap & BIT(2)) >> 2;
+ res += (chain_bitmap & BIT(4)) >> 4;
+ return res;
+}
+
/**
* iwl_set_rxon_chain - Set up Rx chain usage in "staging" RXON image
*
@@ -750,25 +761,35 @@ void iwl_set_rxon_chain(struct iwl_priv *priv)
{
bool is_single = is_single_rx_stream(priv);
bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
- u8 idle_rx_cnt, active_rx_cnt;
+ u8 idle_rx_cnt, active_rx_cnt, valid_rx_cnt;
+ u32 active_chains;
u16 rx_chain;
/* Tell uCode which antennas are actually connected.
* Before first association, we assume all antennas are connected.
* Just after first association, iwl_chain_noise_calibration()
* checks which antennas actually *are* connected. */
- rx_chain = priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS;
+ if (priv->chain_noise_data.active_chains)
+ active_chains = priv->chain_noise_data.active_chains;
+ else
+ active_chains = priv->hw_params.valid_rx_ant;
+
+ rx_chain = active_chains << RXON_RX_CHAIN_VALID_POS;
/* How many receivers should we use? */
active_rx_cnt = iwl_get_active_rx_chain_count(priv);
idle_rx_cnt = iwl_get_idle_rx_chain_count(priv, active_rx_cnt);
- /* correct rx chain count accoridng hw settings */
- if (priv->hw_params.rx_chains_num < active_rx_cnt)
- active_rx_cnt = priv->hw_params.rx_chains_num;
- if (priv->hw_params.rx_chains_num < idle_rx_cnt)
- idle_rx_cnt = priv->hw_params.rx_chains_num;
+ /* correct rx chain count according hw settings
+ * and chain noise calibration
+ */
+ valid_rx_cnt = iwl_count_chain_bitmap(active_chains);
+ if (valid_rx_cnt < active_rx_cnt)
+ active_rx_cnt = valid_rx_cnt;
+
+ if (valid_rx_cnt < idle_rx_cnt)
+ idle_rx_cnt = valid_rx_cnt;
rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS;
rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS;
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 7934f56..6e150f6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -699,8 +699,9 @@ enum iwl4965_false_alarm_state {
enum iwl4965_chain_noise_state {
IWL_CHAIN_NOISE_ALIVE = 0, /* must be 0 */
- IWL_CHAIN_NOISE_ACCUMULATE = 1,
- IWL_CHAIN_NOISE_CALIBRATED = 2,
+ IWL_CHAIN_NOISE_ACCUMULATE,
+ IWL_CHAIN_NOISE_CALIBRATED,
+ IWL_CHAIN_NOISE_DONE,
};
enum iwl4965_calib_enabled_state {
@@ -758,17 +759,18 @@ struct iwl_sensitivity_data {
/* Chain noise (differential Rx gain) calib data */
struct iwl_chain_noise_data {
- u8 state;
- u16 beacon_count;
+ u32 active_chains;
u32 chain_noise_a;
u32 chain_noise_b;
u32 chain_noise_c;
u32 chain_signal_a;
u32 chain_signal_b;
u32 chain_signal_c;
+ u16 beacon_count;
u8 disconn_array[NUM_RX_CHAINS];
u8 delta_gain_code[NUM_RX_CHAINS];
u8 radio_write;
+ u8 state;
};
#define EEPROM_SEM_TIMEOUT 10 /* milliseconds */
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 16f834d..bd6f600 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -252,12 +252,21 @@ static int iwl_update_power_command(struct iwl_priv *priv,
/*
* calucaute the final power mode index
*/
-int iwl_power_update_mode(struct iwl_priv *priv, u8 refresh)
+int iwl_power_update_mode(struct iwl_priv *priv, bool force)
{
struct iwl_power_mgr *setting = &(priv->power_data);
int ret = 0;
u16 uninitialized_var(final_mode);
+ /* Don't update the RX chain when chain noise calibration is running */
+ if (priv->chain_noise_data.state != IWL_CHAIN_NOISE_DONE &&
+ priv->chain_noise_data.state != IWL_CHAIN_NOISE_ALIVE) {
+ IWL_DEBUG_POWER("Cannot update the power, chain noise "
+ "calibration running: %d\n",
+ priv->chain_noise_data.state);
+ return -EAGAIN;
+ }
+
/* If on battery, set to 3,
* if plugged into AC power, set to CAM ("continuously aware mode"),
* else user level */
@@ -285,7 +294,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, u8 refresh)
final_mode = IWL_POWER_MODE_CAM;
if (!iwl_is_rfkill(priv) && !setting->power_disabled &&
- ((setting->power_mode != final_mode) || refresh)) {
+ ((setting->power_mode != final_mode) || force)) {
struct iwl_powertable_cmd cmd;
if (final_mode != IWL_POWER_MODE_CAM)
@@ -359,35 +368,26 @@ EXPORT_SYMBOL(iwl_power_enable_management);
/* set user_power_setting */
int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode)
{
- int ret = 0;
-
if (mode > IWL_POWER_LIMIT)
return -EINVAL;
priv->power_data.user_power_setting = mode;
- ret = iwl_power_update_mode(priv, 0);
-
- return ret;
+ return iwl_power_update_mode(priv, 0);
}
EXPORT_SYMBOL(iwl_power_set_user_mode);
-
/* set system_power_setting. This should be set by over all
* PM application.
*/
int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode)
{
- int ret = 0;
-
if (mode > IWL_POWER_LIMIT)
return -EINVAL;
priv->power_data.system_power_setting = mode;
- ret = iwl_power_update_mode(priv, 0);
-
- return ret;
+ return iwl_power_update_mode(priv, 0);
}
EXPORT_SYMBOL(iwl_power_set_system_mode);
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
index aa99f36..a5c334f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.h
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -80,7 +80,7 @@ struct iwl_power_mgr {
void iwl_setup_power_deferred_work(struct iwl_priv *priv);
void iwl_power_cancel_timeout(struct iwl_priv *priv);
-int iwl_power_update_mode(struct iwl_priv *priv, u8 refresh);
+int iwl_power_update_mode(struct iwl_priv *priv, bool force);
int iwl_power_disable_management(struct iwl_priv *priv, u32 ms);
int iwl_power_enable_management(struct iwl_priv *priv);
int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode);
--
1.5.3.6
next prev parent reply other threads:[~2008-09-03 3:31 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-09-03 3:26 [PATCH 00/39] iwlwifi driver 09/03 updates Zhu Yi
2008-09-03 3:26 ` [PATCH 01/39] iwlwifi : Added bss_info_changed callback to 3945 Zhu Yi
2008-09-03 3:26 ` [PATCH 02/39] iwlwifi: W/A for the TSF correction in IBSS Zhu Yi
2008-09-03 3:26 ` [PATCH 03/39] iwlwifi: clean up hw scan handler Zhu Yi
2008-09-03 3:26 ` [PATCH 04/39] iwlwifi: remove obsolete 4965 forward declarations Zhu Yi
2008-09-03 3:26 ` [PATCH 05/39] iwlwifi: allow consecutive scans in unassociated state Zhu Yi
2008-09-03 3:26 ` [PATCH 06/39] iwlwifi: align set channel with mac80211 Zhu Yi
2008-09-03 3:26 ` [PATCH 07/39] iwl3945: fix unbalanced mutex Zhu Yi
2008-09-03 3:26 ` [PATCH 08/39] iwl3945: replace association and beacon hooks with bss_info_changed cb Zhu Yi
2008-09-03 3:26 ` [PATCH 09/39] iwlwifi: fix hidden ssid discovery in passive channels Zhu Yi
2008-09-03 3:26 ` [PATCH 10/39] iwl3945: removed bg_post_associate work Zhu Yi
2008-09-03 3:26 ` [PATCH 11/39] iwl3945: avoid redundant iwl3945_get_active_dwell_time Zhu Yi
2008-09-03 3:26 ` [PATCH 12/39] iwlwifi: use strict_strtoul instead of simple_strtoul Zhu Yi
2008-09-03 3:26 ` [PATCH 13/39] iwlwifi: void full rxon on rx chain changes Zhu Yi
2008-09-03 3:26 ` [PATCH 14/39] iwlwifi: replace readl and writel with io/read/write/32 Zhu Yi
2008-09-03 3:26 ` [PATCH 15/39] iwlwifi: remove rfkill warning from iwl-io Zhu Yi
2008-09-03 3:26 ` [PATCH 16/39] iwlwifi: fix apm_stop function Zhu Yi
2008-09-03 3:26 ` [PATCH 17/39] iwlwifi: generic init calibrations framework Zhu Yi
2008-09-03 3:26 ` [PATCH 18/39] iwlwifi: call apm stop on exit Zhu Yi
2008-09-03 3:26 ` [PATCH 19/39] iwlwifi: fix strict_strtoul error checking Zhu Yi
2008-09-03 3:26 ` [PATCH 20/39] iwlwifi: use station's mimo power save values Zhu Yi
2008-09-03 3:26 ` [PATCH 21/39] iwlwifi: fix rx_chain computation Zhu Yi
2008-09-03 3:26 ` [PATCH 22/39] iwlwifi: fix 64bit platform firmware loading Zhu Yi
2008-09-03 3:26 ` [PATCH 23/39] mac80211: change MIMO_PS to SM_PS Zhu Yi
2008-09-03 3:26 ` [PATCH 24/39] iwlwifi: " Zhu Yi
2008-09-03 3:26 ` [PATCH 25/39] ath9k: " Zhu Yi
2008-09-03 3:26 ` [PATCH 26/39] iwlwifi: remove double definition of SM PS Zhu Yi
2008-09-03 3:26 ` [PATCH 27/39] iwlwifi: rename ps_mode to sm_ps Zhu Yi
2008-09-03 3:26 ` [PATCH 28/39] iwlwifi: workaround interrupt handling no some platforms Zhu Yi
2008-09-03 3:26 ` [PATCH 29/39] iwlwifi: cleanup PCI register handling Zhu Yi
2008-09-03 3:26 ` [PATCH 30/39] iwlwifi: allow association on radar channel in power save Zhu Yi
2008-09-03 3:26 ` [PATCH 31/39] iwlwifi: fix memory allocation of TX command Zhu Yi
2008-09-03 3:26 ` [PATCH 32/39] iwlwifi: fix host command header according the HW spec Zhu Yi
2008-09-03 3:26 ` Zhu Yi [this message]
2008-09-03 3:26 ` [PATCH 34/39] iwlwifi: take a fresh set of supported rates at each cycle Zhu Yi
2008-09-03 3:26 ` [PATCH 35/39] iwlwifi: remove bad language from the comments Zhu Yi
2008-09-03 3:26 ` [PATCH 36/39] iwlwifi: remove uneeded declarations Zhu Yi
2008-09-03 3:26 ` [PATCH 37/39] iwlwifi: fix compile warning Zhu Yi
2008-09-03 3:26 ` [PATCH 38/39] iwl3945: enable active scanning on active channels Zhu Yi
2008-09-03 3:26 ` [PATCH 39/39] iwlwifi: enable packet injection for iwlagn Zhu Yi
2008-09-03 14:28 ` [PATCH 31/39] iwlwifi: fix memory allocation of TX command Tomas Winkler
2008-09-05 21:14 ` [PATCH 08/39] iwl3945: replace association and beacon hooks with bss_info_changed cb Johannes Berg
2008-09-05 22:50 ` Kolekar, Abhijeet
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1220412419-15404-34-git-send-email-yi.zhu@intel.com \
--to=yi.zhu@intel.com \
--cc=emmanuel.grumbach@intel.com \
--cc=linux-wireless@vger.kernel.org \
--cc=linville@tuxdriver.com \
--cc=tomas.winkler@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox