diff options
author | Grumbach, Emmanuel <emmanuel.grumbach@intel.com> | 2008-09-02 23:26:53 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-09-11 15:53:31 -0400 |
commit | 04816448d8b77551834c9ea01e407ef5f0042f0f (patch) | |
tree | e3c1e019045e0d275f67f79b32ca3fae5e74c2ae /drivers/net/wireless/iwlwifi/iwl-core.c | |
parent | 12837be1c127e6fba2e3f916a18fc202a9889af2 (diff) |
iwlwifi: use the results from disconnected antenna algorithm
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>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-core.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index dbeaca15dda..46683eacfdc 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) | |||
740 | return idle_cnt; | 740 | return idle_cnt; |
741 | } | 741 | } |
742 | 742 | ||
743 | /* up to 4 chains */ | ||
744 | static u8 iwl_count_chain_bitmap(u32 chain_bitmap) | ||
745 | { | ||
746 | u8 res; | ||
747 | res = (chain_bitmap & BIT(0)) >> 0; | ||
748 | res += (chain_bitmap & BIT(1)) >> 1; | ||
749 | res += (chain_bitmap & BIT(2)) >> 2; | ||
750 | res += (chain_bitmap & BIT(4)) >> 4; | ||
751 | return res; | ||
752 | } | ||
753 | |||
743 | /** | 754 | /** |
744 | * iwl_set_rxon_chain - Set up Rx chain usage in "staging" RXON image | 755 | * iwl_set_rxon_chain - Set up Rx chain usage in "staging" RXON image |
745 | * | 756 | * |
@@ -750,25 +761,35 @@ void iwl_set_rxon_chain(struct iwl_priv *priv) | |||
750 | { | 761 | { |
751 | bool is_single = is_single_rx_stream(priv); | 762 | bool is_single = is_single_rx_stream(priv); |
752 | bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status); | 763 | bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status); |
753 | u8 idle_rx_cnt, active_rx_cnt; | 764 | u8 idle_rx_cnt, active_rx_cnt, valid_rx_cnt; |
765 | u32 active_chains; | ||
754 | u16 rx_chain; | 766 | u16 rx_chain; |
755 | 767 | ||
756 | /* Tell uCode which antennas are actually connected. | 768 | /* Tell uCode which antennas are actually connected. |
757 | * Before first association, we assume all antennas are connected. | 769 | * Before first association, we assume all antennas are connected. |
758 | * Just after first association, iwl_chain_noise_calibration() | 770 | * Just after first association, iwl_chain_noise_calibration() |
759 | * checks which antennas actually *are* connected. */ | 771 | * checks which antennas actually *are* connected. */ |
760 | rx_chain = priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS; | 772 | if (priv->chain_noise_data.active_chains) |
773 | active_chains = priv->chain_noise_data.active_chains; | ||
774 | else | ||
775 | active_chains = priv->hw_params.valid_rx_ant; | ||
776 | |||
777 | rx_chain = active_chains << RXON_RX_CHAIN_VALID_POS; | ||
761 | 778 | ||
762 | /* How many receivers should we use? */ | 779 | /* How many receivers should we use? */ |
763 | active_rx_cnt = iwl_get_active_rx_chain_count(priv); | 780 | active_rx_cnt = iwl_get_active_rx_chain_count(priv); |
764 | idle_rx_cnt = iwl_get_idle_rx_chain_count(priv, active_rx_cnt); | 781 | idle_rx_cnt = iwl_get_idle_rx_chain_count(priv, active_rx_cnt); |
765 | 782 | ||
766 | /* correct rx chain count accoridng hw settings */ | ||
767 | if (priv->hw_params.rx_chains_num < active_rx_cnt) | ||
768 | active_rx_cnt = priv->hw_params.rx_chains_num; | ||
769 | 783 | ||
770 | if (priv->hw_params.rx_chains_num < idle_rx_cnt) | 784 | /* correct rx chain count according hw settings |
771 | idle_rx_cnt = priv->hw_params.rx_chains_num; | 785 | * and chain noise calibration |
786 | */ | ||
787 | valid_rx_cnt = iwl_count_chain_bitmap(active_chains); | ||
788 | if (valid_rx_cnt < active_rx_cnt) | ||
789 | active_rx_cnt = valid_rx_cnt; | ||
790 | |||
791 | if (valid_rx_cnt < idle_rx_cnt) | ||
792 | idle_rx_cnt = valid_rx_cnt; | ||
772 | 793 | ||
773 | rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS; | 794 | rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS; |
774 | rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS; | 795 | rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS; |